This commit is contained in:
SantaSpeen 2022-03-17 21:35:46 +03:00
parent f8dd15ef5b
commit 41d84948d2
4 changed files with 79 additions and 29 deletions

View File

@ -1,5 +1,5 @@
__title__ = "gitflic" __title__ = "gitflic"
__version__ = "0.10" __version__ = "0.11"
__description__ = "GitflicApi wrapper" __description__ = "GitflicApi wrapper"
__author__ = "SantaSpeen" __author__ = "SantaSpeen"
__author_email__ = "dir@sssr.dev" __author_email__ = "dir@sssr.dev"

View File

@ -1,18 +1,30 @@
""" """
Main Gitflic API wrapper. Main Gitflic API wrapper.
""" """
from enum import Enum
from .auth import GitflicAuth from .auth import GitflicAuth
from .exceptions import ( from .exceptions import (
NotFound, NoRights, GitflicExceptions NotFound, AccessDenied, GitflicExceptions
) )
API_URL = 'https://api.gitflic.ru' API_URL = 'https://api.gitflic.ru'
def _fix_none(obj):
if isinstance(obj, tuple) or isinstance(obj, list):
obj = list(obj)
for index, item in enumerate(obj):
if item is None:
obj[index] = ''
elif isinstance(obj, dict):
for k, v in obj.items():
if v is None:
obj[k] = ''
return obj
class Gitflic: class Gitflic:
""" """
Gitflic API wrapper. Gitflic API wrapper.
@ -38,11 +50,11 @@ class Gitflic:
url = response.url url = response.url
if code == 403: if code == 403:
raise NoRights(f"Access denied for '{url}'") raise AccessDenied(f"Access denied for '{url}'")
elif code == 404: elif code == 404:
raise NotFound(f"Location '{url}' not found") raise NotFound(f"Location '{url}' not found")
raise GitflicExceptions(f"Gitflic sent unknown error with HTTP code: {code}. Response: {response.text}") raise GitflicExceptions(f"Gitflic sent unknown error with HTTP code: {code}. Url: {url}. Response: {response.text}")
def call(self, method: str, *args, **kwargs): def call(self, method: str, *args, **kwargs):
""" """
@ -53,9 +65,38 @@ class Gitflic:
response = self.session.get(API_URL + method, *args, **kwargs) response = self.session.get(API_URL + method, *args, **kwargs)
return self._response_handler(response) return self._response_handler(response)
def reg_call(self, method: str): def __reg_call_handler(self, *args, end=None, **kwargs):
if end is None:
end = ""
args: list = _fix_none(args)
kwargs: dict = _fix_none(kwargs)
disable_formatting: bool = kwargs.pop("disable_formatting", False)
method: str = kwargs['__gitflic_method_name__']
l = lambda add_to_method="", *_args, **_kwargs: self.call(method+add_to_method, *_args, **_kwargs) # If not need formatting
l.__name__ = method.replace("/", "_") if not disable_formatting:
if len(args) > 0:
try:
if "%" in method:
method %= tuple(args)
else:
method = method.format(*args)
return l except Exception as e:
raise GitflicExceptions(f"Formatting error: {e!r}; In call: '{method}; Args: {args}'")
elif len(kwargs) > 0:
if "%" in method:
method %= kwargs
else:
method = method.format_map(kwargs)
method += end
return self.call(method)
def reg_call(self, method_string: str):
func = lambda *args, **kwargs: self.__reg_call_handler(*args, **kwargs, __gitflic_method_name__=method_string)
func.__name__ = method_string
return func

View File

@ -1,7 +1,6 @@
""" """
Gitflic authentication wrapper. Gitflic authentication wrapper.
""" """
from enum import Enum from enum import Enum
from typing import Union from typing import Union
import logging import logging
@ -9,7 +8,7 @@ import logging
import requests import requests
from .exceptions import AuthError, GitflicExceptions from .exceptions import AuthError, GitflicExceptions
from .__version__ import __version__
OAUTH_URL = "https://oauth.gitflic.ru/oauth/authorize?scope={}&clientId={}&redirectUrl={}&state={}" OAUTH_URL = "https://oauth.gitflic.ru/oauth/authorize?scope={}&clientId={}&redirectUrl={}&state={}"
@ -29,7 +28,7 @@ class GitflicAuth:
""" """
Gitflic authentication wrapper. Gitflic authentication wrapper.
""" """
# noinspection PyTypeChecker # noinspection PyTypeChecker
def __init__(self, def __init__(self,
access_token: str = None, access_token: str = None,
@ -51,7 +50,12 @@ class GitflicAuth:
# Requests. # Requests.
self.session: requests.Session = requests.Session() self.session: requests.Session = requests.Session()
# Auth. # Set headers
self.session.headers = {
"User-Agent": f"gitflic-py/{__version__}",
'Accept': "application/*",
'Authorization': "token "
}
# Token fields. # Token fields.
self.access_token: str = access_token self.access_token: str = access_token
@ -60,7 +64,7 @@ class GitflicAuth:
self.scope: str = scope if not isinstance(scope, GitflicAuthScopes) else scope.value self.scope: str = scope if not isinstance(scope, GitflicAuthScopes) else scope.value
self.client_id: str = client_id self.client_id: str = client_id
self.redirect_url: str = redirect_url self.redirect_url: str = redirect_url
self.state: str = state self.state: str = state
self.refresh_token: str = None self.refresh_token: str = None
self._try_login() self._try_login()
@ -77,21 +81,21 @@ class GitflicAuth:
# OAUTH authorization. # OAUTH authorization.
self._oauth_login() self._oauth_login()
else: else:
if any(self.scope, self.client_id, self.redirect_url, self.state): if any((self.scope, self.client_id, self.redirect_url, self.state)):
raise GitflicExceptions( raise GitflicExceptions(
"Not found one of params for OAUTH, you are required to send ALL params from ('scope', 'client_id', 'redirect_url', 'state')!" "Not found one of params for OAUTH, you are required to send ALL params from ('scope', 'client_id', 'redirect_url', 'state')! "
"See docs: https://gitflic.ru/help/api/access-token." "See docs: https://gitflic.ru/help/api/access-token."
) )
raise GitflicExceptions( raise GitflicExceptions(
"Please pass 'token' param for raw auth or ('scope', 'client_id', 'redirect_url', 'state') params for OAUTH " "Please pass 'token' param for raw auth or ('scope', 'client_id', 'redirect_url', 'state') params for OAUTH "
"See docs: https://gitflic.ru/help/api/access-token." "See docs: https://gitflic.ru/help/api/access-token."
) )
def _oauth_login(self): def _oauth_login(self):
""" """
Tries to login user with OAUTH. Tries to login user with OAUTH.
""" """
self.log.debug("Trying to login with OAUTH...") self.log.debug("Trying to login with OAUTH...")
# OAUTH authorization. # OAUTH authorization.
@ -109,16 +113,14 @@ class GitflicAuth:
""" """
Tries to login user with given access token. Tries to login user with given access token.
""" """
self.log.debug("Trying to login with token...")
if self.access_token: self.log.debug(f"Trying to login with token={self.access_token}...")
self.session.headers.update({
"Authorization": "token " + self.access_token assert isinstance(self.access_token, str)
}) self.session.headers['Authorization'] += self.access_token
self.check_token() self.check_token()
def check_token(self): def check_token(self):
""" """
Checks that current auth session token is valid or not (by making request to get current user). Checks that current auth session token is valid or not (by making request to get current user).
@ -128,7 +130,9 @@ class GitflicAuth:
r = self.session.get("https://api.gitflic.ru/user/me") r = self.session.get("https://api.gitflic.ru/user/me")
if r.status_code == 403: if r.status_code == 403:
raise AuthError("Authentication failed. Invalid token?") e = AuthError("Authentication failed. Invalid token?")
e.response = r
raise e
else: else:
r = r.json() r = r.json()
self.log.debug(f"Successfully logged as {r.get('username')} {r.get('id')}") self.log.debug(f"Successfully logged as {r.get('username')} {r.get('id')}")

View File

@ -1,6 +1,8 @@
""" """
All exceptions that may be raised from Gitflic API wrapper. All exceptions that may be raised from Gitflic API wrapper.
""" """
from requests import Response
class GitflicExceptions(Exception): class GitflicExceptions(Exception):
error_code: int = 1 error_code: int = 1
@ -12,15 +14,18 @@ class AuthError(GitflicExceptions):
error_code = 403 error_code = 403
reason = None reason = None
reason_ru = None reason_ru = None
response: Response = None
class NoRights(GitflicExceptions): class AccessDenied(GitflicExceptions):
error_code = 403 error_code = 403
reason = "There are no access rights." reason = "There are no access rights."
reason_ru = "Нет прав для доступа." reason_ru = "Нет прав для доступа."
response: Response = None
class NotFound(GitflicExceptions): class NotFound(GitflicExceptions):
error_code = 404 error_code = 404
reason = "No data was found for the query." reason = "No data was found for the query."
reason_ru = "Данные по запросу не найдены." reason_ru = "Данные по запросу не найдены."
response: Response = None