Sanic: AssertionError: yield from wasn't used with future while handling uri /

Created on 11 Apr 2017  ·  4Comments  ·  Source: sanic-org/sanic

Hello. I am a newbie at Sanic and Python3 async/coroutines.
I am trying to write a webserver that fetches a few urls in parallel (with a two seconds timeout) and returns the best result out of them. I have Sanic installed fine and I can run simpler code.
But since I started adding the async code to http get the urls, I'm getting this error:

2017-04-11 01:01:58,137: ERROR: Traceback (most recent call last):
  File "/home/aiu/virtualenv/lib/python3.5/site-packages/sanic/app.py", line 391, in handle_request
    response = await response
  File "/usr/lib/python3.5/asyncio/coroutines.py", line 109, in __next__
    return self.gen.send(None)
  File "testurls.py", line 33, in adreq
    done, not_done = asyncio.wait(tasks,timeout=2, return_when=ALL_COMPLETED)
  File "/usr/lib/python3.5/asyncio/tasks.py", line 355, in wait
    return (yield from _wait(fs, timeout, return_when, loop))
  File "/usr/lib/python3.5/asyncio/tasks.py", line 438, in _wait
    yield from waiter
  File "uvloop/future.pyx", line 233, in __iter__ (uvloop/loop.c:110632)
AssertionError: yield from wasn't used with future

Unfortunately I don't understand where's the problem and Google offers little help.
Could anyone point out what I'm doing wrong here?
Thanks. Below is the code.

import asyncio
import uvloop
from aiohttp import ClientSession
from sanic_useragent import SanicUserAgent
from urllib.parse import urlencode, urlunparse
from concurrent.futures import ALL_COMPLETED
import aiohttp

asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())

from sanic import Sanic
from sanic.response import json

loop = None
app = Sanic(__name__)

SanicUserAgent.init_app(app)

async def fetch(url):
  async with ClientSession() as session:
    async with session.get(url) as response:
        return await response.read()

@app.route("/")
async def adreq(request):
    urls = ["http://www.google.com","http://www.cnn.com","http://www.nydailynews.com/"]
    tasks = []
    for u in urls:
      task = asyncio.ensure_future(fetch(u))
      #task = loop.create_task(fetch(u))
      tasks.append(task)
    done, not_done = asyncio.wait(tasks,timeout=2, return_when=ALL_COMPLETED)
    return json(done)

if __name__ == "__main__":
  loop = asyncio.get_event_loop()  
  app.run(host="0.0.0.0", port=8000, workers=3, debug=True, loop=loop)

Most helpful comment

done, not_done = await asyncio.wait(tasks,timeout=2, return_when=ALL_COMPLETED)

asyncio.wait is a coroutine function

https://docs.python.org/3/library/asyncio-task.html?highlight=wait#asyncio.wait

All 4 comments

done, not_done = await asyncio.wait(tasks,timeout=2, return_when=ALL_COMPLETED)

asyncio.wait is a coroutine function

https://docs.python.org/3/library/asyncio-task.html?highlight=wait#asyncio.wait

That fixed it. Thanks a lot!

@aiurlano How did you fix the above issue? Can you please share code change you did?

@11ash99 I don't really remember now but I think It was enough to add the await keyword before asyncio.wait call

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Souldat picture Souldat  ·  3Comments

misakar picture misakar  ·  4Comments

woutor picture woutor  ·  3Comments

ZeeRoc picture ZeeRoc  ·  3Comments

jasonab picture jasonab  ·  3Comments