Why doesn't this python aiohttp requests code run asynchronously?

Viewed 48

I'm trying to access an API with aiohttp but something is causing this code to block each iteration.

def main():
    async with aiohttp.ClientSession() as session:
        for i, (image, target) in enumerate(dataset_val):
            image_bytes = pil_to_bytes(image)
            async with session.post('http://localhost:8080/predictions/resnet50', data=image_bytes) as resp:
                print(await resp.text())
                print(i, flush=True, end='\r')


asyncio.run(main())
1 Answers

As explained by @deceze, await will wait for your result inside your loop. If you want to call everything at the same time, you need to call everything from an external loop and gather the results.

Here's a way of doing it

import asyncio
import aiohttp

async def call(session: aiohttp.ClientSession, url: str, image):
    image_bytes = pil_to_bytes(image)
    async with session.post(url, data=image_bytes) as response:
        return await response.text()


async def call_all(url:str, tasks: list):
    async with aiohttp.ClientSession() as session:
        results = await asyncio.gather(
            *[call(session, url, img) for img, target in tasks], 
            return_exceptions=True
        )
        return results


loop = asyncio.get_event_loop()
res = loop.run_until_complete(
    call_all('http://localhost:8080/predictions/resnet50', dataset_val)
)
Related