python aiohttp.web中间件是如何工作的

时间:2016-05-06 23:11:07

标签: python aiohttp

根据文件

  

传入中间件工厂的处理程序是下一个中间件工厂返回的处理程序。最后一个中间件工厂总是接收路由器自己选择的请求处理程序(通过UrlDispatcher.resolve())。

我以为UrlDispatcher.resolve()会返回我指定的注册处理程序,所以我编写了这段代码。根据我的理解,当访问页面127.0.0.1:9000时,索引处理程序将用作m1的处理程序

import logging;
import asyncio
from aiohttp import web

logging.basicConfig(level=logging.INFO)

@asyncio.coroutine
def m1(app,handler):
    def log(request):
        r = yield from handler(request)
        logging.info(str(r))

@asyncio.coroutine
def index(request):
    return web.Response(body=b'<h1>Aswesome</h1>')

@asyncio.coroutine
def names(request):
    return web.Response(text='<h1>%s</h1>' % request.match_info['name'])

@asyncio.coroutine
def init(loop):
    app = web.Application(loop=loop, middlewares=[
        m1
    ])
    app.router.add_route('GET','/',index)
    app.router.add_route('GET','/{name:\w+}',names)
    srv = yield from loop.create_server(app.make_handler(),'127.0.0.1',9000)
    logging.info('server started at http://127.0.0.1:9000')
    return srv

loop = asyncio.get_event_loop()
loop.run_until_complete(init(loop))
loop.run_forever()

当我运行代码并在127.0.0.1:9000访问服务器时,我得到了

  File "/home/os/Documents/Python/web/lib/python3.5/site-packages/aiohttp/web.py", line 90, in handle_request
    resp = yield from handler(request)
TypeError: 'NoneType' object is not callable

在我看来,像NoneType一样作为处理程序传递到m1中间件

1 个答案:

答案 0 :(得分:3)

您的中间件不返回任何内容,但应返回中间件处理程序log。我在代码中添加了一行,返回log

@asyncio.coroutine
def m1(app,handler):
    def log(request):
        r = yield from handler(request)
        logging.info(str(r))
    return log  # changed

有关详细信息,请参阅documentation regarding middlewares。 此外,值得研究Python 3.5,它提供了async/await语法,用于处理等待对象aka coroutines。 aiohttp的贡献者建议使用语法。

请参阅Igor Davydenko的演讲中的官方PEP-492slides,并介绍新语法。