89 lines
2.9 KiB
Python
Executable File
89 lines
2.9 KiB
Python
Executable File
from django.http import HttpResponse
|
|
from .api_params import *
|
|
|
|
|
|
api_methods_dict = {}
|
|
|
|
|
|
def api_make_response(response):
|
|
return API_OK_OBJ | {"response": response}
|
|
|
|
|
|
# def api_make_param(name, arg_class, description, required=True):
|
|
# return {
|
|
# "name": name,
|
|
# "type": arg_class,
|
|
# "description": description,
|
|
# "required": required
|
|
# }
|
|
|
|
# API_PARAM_ACCESS_TOKEN = api_make_param(
|
|
# "access_token",
|
|
# AccessToken,
|
|
# "<i>Токен</i>, выданный методом <code>account.auth</code>"
|
|
# )
|
|
|
|
|
|
def api_method(func_name, doc="", params: list or None = None, returns=""):
|
|
"""
|
|
Декоратор для методов API, автоматически валидирует и передает параметры методам
|
|
"""
|
|
def actual_decorator(func):
|
|
async def wrapper(__raw_request, **kwargs):
|
|
print(f"> call method {func_name} with params {kwargs}. method params: {params}")
|
|
|
|
errors = []
|
|
func_args = {}
|
|
for p in params:
|
|
try:
|
|
if not isinstance(p, ApiParam):
|
|
raise Exception(API_ERROR_INTERNAL_ERROR, f"param {p} is not instance of ApiParam class")
|
|
|
|
name = p.get_name()
|
|
|
|
if isinstance(p, ApiRequestParam):
|
|
func_args[name] = __raw_request
|
|
else:
|
|
value = kwargs[name] if name in kwargs else None
|
|
|
|
if asyncio.iscoroutinefunction(p.validate):
|
|
func_args[name] = await p.validate(value)
|
|
else:
|
|
func_args[name] = p.validate(value)
|
|
|
|
except Exception as ex:
|
|
errors.append(ex)
|
|
# print(f"errors: {errors}, args: {func_args}")
|
|
if len(errors) > 0:
|
|
if len(errors) == 1:
|
|
return make_error_object(errors[0])
|
|
else:
|
|
return make_error_object(errors)
|
|
else:
|
|
try:
|
|
if asyncio.iscoroutinefunction(func):
|
|
out = await func(**func_args)
|
|
else:
|
|
out = func(**func_args)
|
|
except Exception as ex:
|
|
return make_error_object(ex)
|
|
|
|
if out is None:
|
|
return make_error_object(Exception(API_ERROR_INTERNAL_ERROR, "method returned null object"))
|
|
|
|
if not isinstance(out, dict) and not isinstance(out, HttpResponse):
|
|
return make_error_object(Exception(API_ERROR_INTERNAL_ERROR, "method returned invalid object type"))
|
|
|
|
return out
|
|
|
|
api_methods_dict[func_name] = {
|
|
"doc": doc,
|
|
"params": params,
|
|
"func": wrapper,
|
|
"returns": returns
|
|
}
|
|
return wrapper
|
|
|
|
return actual_decorator
|
|
|