Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there an essential difference between await and async-with while doing request in aiohttp?

My question is about the right way of making response in 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?

like image 732
Fedor Soldatkin Avatar asked Dec 20 '20 12:12

Fedor Soldatkin


People also ask

Can I use Asyncio with requests?

asyncio enables to actually handle many concurrent (not parallel!) requests with no threads at all (well, just one). However, requests does not support asyncio so you need to create threads to get concurrency.

Is aiohttp better than requests?

This indicates that aiohttp has slight advantage compared to Requests when it comes to making an API call to the async route operation of an ASGI server. Having said that, please be reminded that aiohttp will not increase your performance if the bottleneck is not mainly due to an I/O operation.

What does await do in Asyncio?

The keyword await passes function control back to the event loop. (It suspends the execution of the surrounding coroutine.) If Python encounters an await f() expression in the scope of g() , this is how await tells the event loop, “Suspend execution of g() until whatever I'm waiting on—the result of f() —is returned.

Are Python requests asynchronous?

Asynchronous code has increasingly become a mainstay of Python development. With asyncio becoming part of the standard library and many third party packages providing features compatible with it, this paradigm is not going away anytime soon.


1 Answers

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.

like image 62
MisterMiyagi Avatar answered Oct 04 '22 03:10

MisterMiyagi