Source code for brink.decorators

import asyncio


[docs]def require_request_model(cls, *args, validate=True, **kwargs): """ Makes a handler require that a request body that map towards the given model is provided. Unless the ``validate`` option is set to ``False`` the data will be validated against the model's fields. The model will be passed to the handler as the last positional argument. :: @require_request_model(Model) async def handle_model(request, model): return 200, model """ def decorator(handler): async def new_handler(request): body = await request.json() model = cls(**body) if validate: model.validate() return await handler(request, *args, model, **kwargs) return new_handler return decorator
[docs]def use_ws_subhandlers(handler): """ Allows the handler to return any number of **subhandlers** that will be run in parallel. This makes it much cleaner and easier to write a handler that both listens for incoming messages on the socket connection, while also watching a changefeed from RethinkDB. Example usage :: @use_ws_subhandlers async def handle_feed(request, ws): async def handle_incoming(_, ws): async for msg in ws: await Item(value=msg.data).save() async def handle_change(_, ws): async for item in await Item.changes(): ws.send_json(item) return [handle_incoming, handle_change] """ async def new_handler(request, ws): handlers = await handler(request, ws) tasks = [request.app.loop.create_task(h(request, ws)) for h in handlers] try: await asyncio.gather(*tasks) finally: for task in tasks: task.cancel() await ws.close() return new_handler