代码之家  ›  专栏  ›  技术社区  ›  Alexis.Rolland user2915097

AIOHTTP中是否有类似于烧瓶中的后请求方法?

  •  1
  • Alexis.Rolland user2915097  · 技术社区  · 7 年前

    这个烧瓶很好 @app.after_request decorator,允许在处理HTTP请求后执行方法。参见文档 here .

    你将如何实现类似的模式 AIOHTTP ? 通常在处理请求后发送日志。

    1 回复  |  直到 7 年前
        1
  •  2
  •   Martijn Pieters    7 年前

    这个 aiohttp Web服务器支持 signals ,这是要在特定点调用的挂钩。

    这个 Application.on_response_prepare signal 道德上等同于烧瓶 after_request 处理程序。在准备返回客户机时使用它来修改响应:

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

    信号接收两个 request response 物体。如果要实现 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
    

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