Есть ли метод после запроса в aiohttp, как в фляге

Flask предоставляет этот хороший декоратор @app.after_request, который позволяет выполнять метод после обработки http-запроса. См. документацию здесь.

Как бы вы добились аналогичного результата с помощью aiohttp? Обычно для отправки журналов после обработки запроса.


person Alexis.Rolland    schedule 27.07.2018    source источник
comment
Это не лучшая ссылка на документацию для after_request. Попробуйте flask.pocoo.org/docs/1.0/ reqcontext/ и flask.pocoo.org/docs/ 1.0/api/#flask.Flask.after_request вместо этого.   -  person Martijn Pieters    schedule 27.07.2018
comment
Ссылка, которую вы дали, предназначена для конкретного рецепта настройки одноразовых after_request вызовов для определенного запроса только.   -  person Martijn Pieters    schedule 27.07.2018
comment
@MartijnPieters сделал, спасибо   -  person Alexis.Rolland    schedule 27.07.2018


Ответы (1)


Веб-сервер aiohttp поддерживает сигналы< /a>, которые являются хуками, вызываемыми в определенных точках.

Application.on_response_prepare сигнал – это моральный эквивалент Обработчик after_request Flask. Используйте его, чтобы изменить ответ, поскольку он готовится к возврату клиенту:

async def on_prepare(request, response):
    response.headers['My-Header'] = 'value'

app.on_response_prepare.append(on_prepare)

Сигнал принимает объекты request и response. Если вы хотите реализовать шаблон Flask для регистрации обратного вызова для каждого запроса и используете Python 3.7, вы можете использовать contextvars переменную контекста :

from contextvars import ContextVar
from typing import Iterable, Callable

from aiohttp import web


PrepareCallback = Callable[[web.Request, web.StreamResponse], None]
call_on_prepare: ContextVar[Iterable[PrepareCallback]] = ContextVar('call_on_prepare', ())


async def per_request_callbacks(request, response):
    # executed sequentially, in order of registration!
    for callback in call_on_prepare.get():
        await callback(request, response)


app.on_response_prepare.append(per_request_callbacks)


def responce_prepare_after_this_request(awaitable):
    call_on_prepare.set(call_on_prepare.get() + (awaitable,))
    return awaitable

затем используйте его так в запросе:

def invalidate_username_cache():
    @responce_prepare_after_this_request
    async def delete_username_cookie(request, response):
        response.del_cookie('username')
        return response

Если вам нужно поддерживать версии Python ‹ 3.7, вам придется вместо этого хранить список обратных вызовов в объектах app, request или response; см. раздел обмен данными aiohttp часто задаваемых вопросов. Лично я считаю, что contextvars здесь является лучшим шаблоном, так как это обеспечивает лучшую инкапсуляцию для таких утилит, как responce_prepare_after_this_request, которые теперь можно распространять отдельно, не опасаясь конфликта с другим набором данных в сопоставлениях объектов aiohttp.web.

person Martijn Pieters    schedule 27.07.2018