2017-06-30 1 views
2

Considérez le code suivant:aiohttp: chaîne de décorateurs séquence

from aiohttp_mako import template 

def authorize(): 
    def wrapper(func): 
     @asyncio.coroutine 
     @functools.wraps(func) 
     def wrapped(*args): 
      allowed = # Some auth stuff 
      if not allowed: 
       return HTTPUnauthorized() 
      return func() 
     return wrapped 
    return wrapper 


@authorize() 
@template('admin.mak') 
async def admin(request): 
    return dict(ok=True) 

Je me attends authorize() 'wrapper pour obtenir template décorateur comme func pour que je puisse retourner le Response qu'il génère dans mon authorize décorateur. Mais authorize() 'wrapper prend la admin() coroutine comme func et il finit avec

File "/Users/etemin/virtualenvs/onlinelux/lib/python3.5/site-packages/aiohttp/web.py", line 306, in _handle 
    resp = yield from handler(request) 
File "/Users/etemin/virtualenvs/onlinelux/lib/python3.5/site-packages/aiohttp_session/__init__.py", line 134, in middleware 
    raise RuntimeError("Expect response, not {!r}", type(response)) 
RuntimeError: ('Expect response, not {!r}', <class 'generator'>) 

Parce qu'il essaie de retourner le coroutine. Comment devrais-je faire pour retourner le décorateur template?

Répondre

3

Vous avez enveloppé une co-routine, vous devez qui attendent co-routine (rendement de celui-ci):

def authorize(): 
    def wrapper(func): 
     @asyncio.coroutine 
     @functools.wraps(func) 
     def wrapped(*args): 
      allowed = # Some auth stuff 
      if not allowed: 
       return HTTPUnauthorized() 
      return yield from func() 
     return wrapped 
    return wrapper 

Puisque vous utilisez déjà la syntaxe async/await, je il suffit d'utiliser que là aussi et ne pas utiliser @asyncio.coroutine:

def authorize(): 
    async def wrapper(func): 
     @functools.wraps(func) 
     async def wrapped(*args): 
      allowed = # Some auth stuff 
      if not allowed: 
       return HTTPUnauthorized() 
      return await func() 
     return wrapped 
    return wrapper 

Notez que j'attendis sur func() là, et a renvoyé le résultat.

+0

Nous vous remercions de votre réponse. J'ai rencontré quelque chose de vraiment étrange pour moi. La syntaxe 'yield' soulève RuntimeError: ('Expect response, not {! R}', )' 'mais la même syntaxe' async/await' fonctionne bien! Comment venir? – Juggernaut

+1

@Juggernaut: ah, j'ai oublié un 'return', ajouté maintenant. Désolé pour ça! –