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): | ||||
Show All 9 Lines | async def decode_request(request): | ||||
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/json', render_json), | ||||
('application/x-msgpack', render_msgpack), | ('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 |