Flask提供了一个很好的@app.after_request装饰器,该装饰器允许在处理http请求之后执行一个方法。请参阅文档here

如何使用aiohttp实现类似的模式?
通常在处理请求后发送日志。

最佳答案

aiohttp Web服务器支持signals,这是在特定位置调用的钩子。

Application.on_response_prepare signal在道德上等同于Flask的after_request处理程序。在准备将其返回给客户端时,可以使用它来修改响应:

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

app.on_response_prepare.append(on_prepare)


该信号同时接收requestresponse对象。如果要实现Flask pattern for registering a callback per request,并且正在使用Python 3.7,则可以使用contextvars context variable

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


如果需要支持3.7以下的Python版本,则必须将回调列表存储在apprequestresponse对象上;请参阅aiohttp常见问题解答中的data sharing section。就我个人而言,我认为contextvars是更好的模式,因为它为responce_prepare_after_this_request之类的实用程序提供了更好的封装,它们现在可以单独分发,而不必担心与aiohttp.web对象映射中的其他数据集发生冲突。

关于python - 是否像 flask 中一样在aiohttp中有一个后请求方法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51555309/

10-12 19:39