aiohttp
Official aiohttp documentation gives us the example of making an async query:
session = aiohttp.ClientSession()
async with session.get('http://httpbin.org/get') as resp:
print(resp.status)
print(await resp.text())
await session.close()
I cannot understand, why is the context manager here. All i have found is that __aexit__()
method awaits resp.release()
method. But the documentation also tells that awaiting resp.release()
is not necessary at general.
That all really confuses me.
Why should i do that way if i find the code below more readable and not so nested?
session = aiohttp.ClientSession()
resp = await session.get('http://httpbin.org/get')
print(resp.status)
print(await resp.text())
# I finally have not get the essence of this method.
# I've tried both using and not using this method in my code,
# I've not found any difference in behaviour.
# await resp.release()
await session.close()
I have dug into aiohttp.ClientSession
and its context manager sources, but i have not found anything that could clarify the situation.
In the end, my question: what's the difference?
Explicitly managing a response via async with
, is not necessary but advisable. The purpose of async with
for response objects is to safely and promptly release resources used by the response (via a call to resp.release()
). That is, even if an error occurs the resources are freed and available for further requests/responses.
Otherwise, aiohttp
will also release the response resources but without guarantee of promptness. The worst case is that this is delayed for an arbitrary time, i.e. up to the end of the application and timeout of external resources (such as sockets).
The difference is not noticeable if no errors occur (in which case aiohttp
cleans up unused resources) and/or if the application is short (in which case there are enough resources to not need re-use). However, since errors may occur unexpectedly and aiohttp
is designed for many requests/responses, it is advisable to always default to prompt cleanup via async with
.