How to not await in a loop with asyncio?
Question: Here is a toy example that downloads the home page from several websites using
asyncio and aiohttp:

    
    
    import asyncio
    import aiohttp
    
    sites = [
        "http://google.com",
        "http://reddit.com",
        "http://wikipedia.com",
        "http://afpy.org",
        "http://httpbin.org",
        "http://stackoverflow.com",
        "http://reddit.com"
    ]
    
    
    async def main(sites):
        for site in sites:
            download(site)
    
    
    async def download(site):
        response = await client.get(site)
        content = await response.read()
        print(site, len(content))
    
    
    loop = asyncio.get_event_loop()
    client = aiohttp.ClientSession(loop=loop)
    content = loop.run_until_complete(main(sites))
    client.close()
    

If I run it, I get:

    
    
    RuntimeWarning: coroutine 'download' was never awaited
    

But I don't want to await it.

In twisted I can do:

    
    
    for site in sites:
        download(site)
    

And If I don't explicitly "yield" or add a callback to the returned Deferred,
it just runs without blocking nor complaining. I can't access the result, but
in this case I don't need it.

In JS I can do:

    
    
    site.forEarch(site){
        donwload(site)
    }
    

And again, it doesn't block nor does it requires anything from my part.

I found a way to do:

    
    
    async def main(sites):
        await asyncio.wait([download(site) for site in sites])
    

But:

    
    
    - this is really not obvious to find it out. I it's hard to remember.
    - it's hard to understand what it does. "waits" seems to say "i block", but does not convey clearly it block for the entire list of coroutine to finish.
    - you can't pass in a generator, it needs to be a real list, which i feels really unatural in Python.
    - what if I have only ONE awaitable ? 
    - what if I don't want to wait at all on my tasks, and just schedule them for execution then carry on with the rest of my code ?
    - it's way more verbose thant twisted and JS solution.
    

It there a better way ?


Answer: In order to schedule a coroutine as a task, use
[asyncio.ensure_future](https://docs.python.org/3/library/asyncio-
task.html#asyncio.ensure_future):

    
    
    for site in sites:
        coro = download(site)
        future = asyncio.ensure_future(coro)
    

It replaces the deprecated function
[asyncio.async](https://docs.python.org/3/library/asyncio-
task.html#asyncio.async) in version 3.4.4.

Then you can manage those futures using `await`,
[asyncio.wait](https://docs.python.org/3/library/asyncio-
task.html#asyncio.wait) or
[asyncio.gather](https://docs.python.org/3/library/asyncio-
task.html#asyncio.gather).

