Changeset View
Changeset View
Standalone View
Standalone View
swh/core/api/asynchronous.py
Show All 15 Lines | |||||
from .serializers import exception_to_dict | from .serializers import exception_to_dict | ||||
from aiohttp_utils import negotiation, Response | from aiohttp_utils import negotiation, Response | ||||
def encode_msgpack(data, **kwargs): | def encode_msgpack(data, **kwargs): | ||||
return aiohttp.web.Response( | return aiohttp.web.Response( | ||||
body=msgpack_dumps(data), | body=msgpack_dumps(data), | ||||
headers=multidict.MultiDict( | headers=multidict.MultiDict({"Content-Type": "application/x-msgpack"}), | ||||
{'Content-Type': 'application/x-msgpack'}), | **kwargs, | ||||
**kwargs | |||||
) | ) | ||||
encode_data_server = Response | encode_data_server = Response | ||||
def render_msgpack(request, data): | def render_msgpack(request, data): | ||||
return msgpack_dumps(data) | return msgpack_dumps(data) | ||||
def render_json(request, data): | def render_json(request, data): | ||||
return json_dumps(data) | return json_dumps(data) | ||||
async def decode_request(request): | async def decode_request(request): | ||||
content_type = request.headers.get('Content-Type').split(';')[0].strip() | content_type = request.headers.get("Content-Type").split(";")[0].strip() | ||||
data = await request.read() | data = await request.read() | ||||
if not data: | if not data: | ||||
return {} | return {} | ||||
if content_type == 'application/x-msgpack': | if content_type == "application/x-msgpack": | ||||
r = msgpack_loads(data) | r = msgpack_loads(data) | ||||
elif content_type == 'application/json': | elif content_type == "application/json": | ||||
r = json_loads(data) | r = json_loads(data) | ||||
else: | else: | ||||
raise ValueError('Wrong content type `%s` for API request' | raise ValueError("Wrong content type `%s` for API request" % content_type) | ||||
% content_type) | |||||
return r | return r | ||||
async def error_middleware(app, handler): | async def error_middleware(app, handler): | ||||
async def middleware_handler(request): | async def middleware_handler(request): | ||||
try: | try: | ||||
return await handler(request) | return await handler(request) | ||||
except Exception as e: | except Exception as e: | ||||
if isinstance(e, aiohttp.web.HTTPException): | if isinstance(e, aiohttp.web.HTTPException): | ||||
raise | raise | ||||
logging.exception(e) | logging.exception(e) | ||||
res = exception_to_dict(e) | res = exception_to_dict(e) | ||||
if isinstance(e, app.client_exception_classes): | if isinstance(e, app.client_exception_classes): | ||||
status = 400 | status = 400 | ||||
else: | else: | ||||
status = 500 | status = 500 | ||||
return encode_data_server(res, status=status) | return encode_data_server(res, status=status) | ||||
return middleware_handler | return middleware_handler | ||||
class RPCServerApp(aiohttp.web.Application): | class RPCServerApp(aiohttp.web.Application): | ||||
client_exception_classes: Tuple[Type[Exception], ...] = () | client_exception_classes: Tuple[Type[Exception], ...] = () | ||||
"""Exceptions that should be handled as a client error (eg. object not | """Exceptions that should be handled as a client error (eg. object not | ||||
found, invalid argument)""" | found, invalid argument)""" | ||||
def __init__(self, *args, middlewares=(), **kwargs): | def __init__(self, *args, middlewares=(), **kwargs): | ||||
middlewares = (error_middleware,) + middlewares | middlewares = (error_middleware,) + middlewares | ||||
# renderers are sorted in order of increasing desirability (!) | # renderers are sorted in order of increasing desirability (!) | ||||
# see mimeparse.best_match() docstring. | # see mimeparse.best_match() docstring. | ||||
renderers = OrderedDict([ | renderers = OrderedDict( | ||||
('application/json', render_json), | [ | ||||
('application/x-msgpack', render_msgpack), | ("application/json", render_json), | ||||
]) | ("application/x-msgpack", render_msgpack), | ||||
] | |||||
) | |||||
nego_middleware = negotiation.negotiation_middleware( | nego_middleware = negotiation.negotiation_middleware( | ||||
renderers=renderers, | renderers=renderers, force_rendering=True | ||||
force_rendering=True) | ) | ||||
middlewares = (nego_middleware,) + middlewares | middlewares = (nego_middleware,) + middlewares | ||||
super().__init__(*args, middlewares=middlewares, **kwargs) | super().__init__(*args, middlewares=middlewares, **kwargs) | ||||
@deprecated(version='0.0.64', | @deprecated(version="0.0.64", reason="Use the RPCServerApp instead") | ||||
reason='Use the RPCServerApp instead') | |||||
class SWHRemoteAPI(RPCServerApp): | class SWHRemoteAPI(RPCServerApp): | ||||
pass | pass |