I have following code snipped:
import aiohttp
import asyncio
async def main():
async with aiohttp.ClientSession() as session:
async with session.get("https://hub.dummyapis.com/delay?seconds=1") as r:
print("Here!")
text = await r.text()
print(text)
asyncio.run(main())
The url I'm calling simply waits for one second, and then returns a 200
.
I thought the Here!
, would be printed immediately, then 1 second would pass (or maybe a tiny bit more, including the overhead to send and receive the request), and then the text will be printed. After all, I'm only await
ing after the print("Here!")
statement. But that's not the case, the Here!
is only printed after 1 second. So i guess that the async with session.get(...) as r
is blocking? My questions:
aiohttp
to wait for the response to be received, or am I misunderstanding async
here? Can I make the session.get(...) as r
unblocking?Is that possible with aiohttp
?
Basically it is an internal implementation. Lets investigate aiohttp implementation and start with following line of the code
async with session.get("https://hub.dummyapis.com/delay?seconds=1") as r:
Get method of ClientSession
returns a context manager called _RequestContextManager
here. If you check this context manager, it is inherited from another context manager called _BaseRequestContextManager
. In the __aenter__
of this context manager, it basically awaits the response of request and returns response. So basically with this line, you already did request to server and it waited for 1 seconds to get response. So it is normal that "Here!" is printed after 1 seconds because the code inside the context manager is executed after response is obtained. If you check, text
method of ClientResponse
, you can see that this methods only gets body of response and decodes it.