risotto/src/risotto/http.py

77 lines
2.5 KiB
Python

from aiohttp.web import Application, Response, get, post, HTTPBadRequest, HTTPInternalServerError, HTTPNotFound
from tiramisu import Config
from json import dumps
from .dispatcher import dispatcher
from .utils import _
from .context import Context
from .error import CallError, NotAllowedError
from .message import get_messages
from .logger import log
from .config import DEBUG
from traceback import print_exc
async def handle(request):
version, uri = request.match_info.get_info()['path'].rsplit('/', 2)[-2:]
context = Context()
context.username = request.match_info.get('username', "Anonymous")
kwargs = await request.json()
try:
text = await dispatcher.call(version,
uri,
context,
public_only=True,
**kwargs)
except NotAllowedError as err:
raise HTTPNotFound(reason=str(err))
except CallError as err:
raise HTTPBadRequest(reason=str(err))
except Exception as err:
if DEBUG:
print_exc()
raise HTTPInternalServerError(reason=str(err))
return Response(text=dumps({'response': text}))
async def api(request):
context = Context()
context.username = request.match_info.get('username', "Anonymous")
path = request.match_info.get_info()['path']
if path.endswith('/'):
path = path[:-1]
version = path.rsplit('/', 1)[-1]
log.info_msg(version, None, context, {}, None, _(f'get {version} API'))
global tiramisu
if not tiramisu:
config = Config(get_messages(load_shortarg=True,
only_public=True)[1])
tiramisu = config.option.dict(remotable='none')
return Response(text=dumps(tiramisu))
def get_app():
""" build all routes
"""
app = Application()
routes = []
uris = list(dispatcher.uris.items())
uris.sort()
for version, uris in dispatcher.uris.items():
print()
print(_('======== Registered messages ========'))
for uri in uris:
web_uri = f'/api/{version}/{uri}'
if dispatcher.messages[uri]['public']:
print(f' - {web_uri}')
else:
pattern = dispatcher.messages[uri]['pattern']
print(f' - {web_uri} (private {pattern})')
routes.append(post(web_uri, handle))
routes.append(get(f'/api/{version}', api))
print()
app.add_routes(routes)
return app
tiramisu = None