nested “async with” using aiohttp
up vote
0
down vote
favorite
I would like to create a scheduler class that uses aiohttp to make API calls. I tried this:
import asyncio
import aiohttp
class MySession:
def __init__(self):
self.session = None
async def __aenter__(self):
async with aiohttp.ClientSession() as session:
self.session = session
return self
async def __aexit__(self, exc_type, exc_val, exc_tb):
if self.session:
await self.session.close()
async def method1():
async with MySession() as s:
async with s.session.get("https://www.google.com") as resp:
if resp.status == 200:
print("successful call!")
loop = asyncio.get_event_loop()
loop.run_until_complete(method1())
loop.close()
but this just results in an error: RuntimeError: Session is closed
. A second approach for the __aenter__
function:
async def __aenter__(self):
self.session = aiohttp.ClientSession()
return self
works well. Is this a good construct? It doesn't adhere to examples of how to use aiohttp. Also wondering why the first approach isn't working?
python python-asyncio aiohttp
add a comment |
up vote
0
down vote
favorite
I would like to create a scheduler class that uses aiohttp to make API calls. I tried this:
import asyncio
import aiohttp
class MySession:
def __init__(self):
self.session = None
async def __aenter__(self):
async with aiohttp.ClientSession() as session:
self.session = session
return self
async def __aexit__(self, exc_type, exc_val, exc_tb):
if self.session:
await self.session.close()
async def method1():
async with MySession() as s:
async with s.session.get("https://www.google.com") as resp:
if resp.status == 200:
print("successful call!")
loop = asyncio.get_event_loop()
loop.run_until_complete(method1())
loop.close()
but this just results in an error: RuntimeError: Session is closed
. A second approach for the __aenter__
function:
async def __aenter__(self):
self.session = aiohttp.ClientSession()
return self
works well. Is this a good construct? It doesn't adhere to examples of how to use aiohttp. Also wondering why the first approach isn't working?
python python-asyncio aiohttp
add a comment |
up vote
0
down vote
favorite
up vote
0
down vote
favorite
I would like to create a scheduler class that uses aiohttp to make API calls. I tried this:
import asyncio
import aiohttp
class MySession:
def __init__(self):
self.session = None
async def __aenter__(self):
async with aiohttp.ClientSession() as session:
self.session = session
return self
async def __aexit__(self, exc_type, exc_val, exc_tb):
if self.session:
await self.session.close()
async def method1():
async with MySession() as s:
async with s.session.get("https://www.google.com") as resp:
if resp.status == 200:
print("successful call!")
loop = asyncio.get_event_loop()
loop.run_until_complete(method1())
loop.close()
but this just results in an error: RuntimeError: Session is closed
. A second approach for the __aenter__
function:
async def __aenter__(self):
self.session = aiohttp.ClientSession()
return self
works well. Is this a good construct? It doesn't adhere to examples of how to use aiohttp. Also wondering why the first approach isn't working?
python python-asyncio aiohttp
I would like to create a scheduler class that uses aiohttp to make API calls. I tried this:
import asyncio
import aiohttp
class MySession:
def __init__(self):
self.session = None
async def __aenter__(self):
async with aiohttp.ClientSession() as session:
self.session = session
return self
async def __aexit__(self, exc_type, exc_val, exc_tb):
if self.session:
await self.session.close()
async def method1():
async with MySession() as s:
async with s.session.get("https://www.google.com") as resp:
if resp.status == 200:
print("successful call!")
loop = asyncio.get_event_loop()
loop.run_until_complete(method1())
loop.close()
but this just results in an error: RuntimeError: Session is closed
. A second approach for the __aenter__
function:
async def __aenter__(self):
self.session = aiohttp.ClientSession()
return self
works well. Is this a good construct? It doesn't adhere to examples of how to use aiohttp. Also wondering why the first approach isn't working?
python python-asyncio aiohttp
python python-asyncio aiohttp
asked Nov 9 at 15:16
user2416984
1611111
1611111
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
up vote
3
down vote
You can't use with
inside a function and have the context manager remain open, no. The with with aiohttp.ClientSession() as session:
block exits as soon as you use return
to exit the __aenter__
coroutine!
For the specific case, entering a aiohttp.ClientSession()
context manager does nothing but return self
. So for that type, just creating the instance and storing it in self.session
, and awaiting on self.session.close()
suffices here, yes.
The general pattern for a nested asynchronous context manager is to await the __aenter__
and __aexit__
methods of a nested async context manager from your own such methods (and perhaps pass along the exception information):
class MySession:
def __init__(self):
self.session = None
async def __aenter__(self):
self.session = aiohttp.ClientSession()
await self.session.__aenter__()
return self
async def __aexit__(self, exc_type, exc_val, exc_tb):
if self.session:
return await self.session.__aexit__(exc_type, exc_val, exc_tb)
Technically speaking, you should first assure that there is an actual __aexit__
attribute before entering a nested context manager:
class MySession:
def __init__(self):
self.session = None
self._session_aexit = None
async def __aenter__(self):
self.session = aiohttp.ClientSession()
self._session_aexit = type(self.session).__aexit__
await self.session.__aenter__()
return self
async def __aexit__(self, exc_type, exc_val, exc_tb):
if self.session:
return await self._session_aexit.__aexit__(
self.session, exc_type, exc_val, exc_tb)
See the official PEP that added the concept.
add a comment |
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
3
down vote
You can't use with
inside a function and have the context manager remain open, no. The with with aiohttp.ClientSession() as session:
block exits as soon as you use return
to exit the __aenter__
coroutine!
For the specific case, entering a aiohttp.ClientSession()
context manager does nothing but return self
. So for that type, just creating the instance and storing it in self.session
, and awaiting on self.session.close()
suffices here, yes.
The general pattern for a nested asynchronous context manager is to await the __aenter__
and __aexit__
methods of a nested async context manager from your own such methods (and perhaps pass along the exception information):
class MySession:
def __init__(self):
self.session = None
async def __aenter__(self):
self.session = aiohttp.ClientSession()
await self.session.__aenter__()
return self
async def __aexit__(self, exc_type, exc_val, exc_tb):
if self.session:
return await self.session.__aexit__(exc_type, exc_val, exc_tb)
Technically speaking, you should first assure that there is an actual __aexit__
attribute before entering a nested context manager:
class MySession:
def __init__(self):
self.session = None
self._session_aexit = None
async def __aenter__(self):
self.session = aiohttp.ClientSession()
self._session_aexit = type(self.session).__aexit__
await self.session.__aenter__()
return self
async def __aexit__(self, exc_type, exc_val, exc_tb):
if self.session:
return await self._session_aexit.__aexit__(
self.session, exc_type, exc_val, exc_tb)
See the official PEP that added the concept.
add a comment |
up vote
3
down vote
You can't use with
inside a function and have the context manager remain open, no. The with with aiohttp.ClientSession() as session:
block exits as soon as you use return
to exit the __aenter__
coroutine!
For the specific case, entering a aiohttp.ClientSession()
context manager does nothing but return self
. So for that type, just creating the instance and storing it in self.session
, and awaiting on self.session.close()
suffices here, yes.
The general pattern for a nested asynchronous context manager is to await the __aenter__
and __aexit__
methods of a nested async context manager from your own such methods (and perhaps pass along the exception information):
class MySession:
def __init__(self):
self.session = None
async def __aenter__(self):
self.session = aiohttp.ClientSession()
await self.session.__aenter__()
return self
async def __aexit__(self, exc_type, exc_val, exc_tb):
if self.session:
return await self.session.__aexit__(exc_type, exc_val, exc_tb)
Technically speaking, you should first assure that there is an actual __aexit__
attribute before entering a nested context manager:
class MySession:
def __init__(self):
self.session = None
self._session_aexit = None
async def __aenter__(self):
self.session = aiohttp.ClientSession()
self._session_aexit = type(self.session).__aexit__
await self.session.__aenter__()
return self
async def __aexit__(self, exc_type, exc_val, exc_tb):
if self.session:
return await self._session_aexit.__aexit__(
self.session, exc_type, exc_val, exc_tb)
See the official PEP that added the concept.
add a comment |
up vote
3
down vote
up vote
3
down vote
You can't use with
inside a function and have the context manager remain open, no. The with with aiohttp.ClientSession() as session:
block exits as soon as you use return
to exit the __aenter__
coroutine!
For the specific case, entering a aiohttp.ClientSession()
context manager does nothing but return self
. So for that type, just creating the instance and storing it in self.session
, and awaiting on self.session.close()
suffices here, yes.
The general pattern for a nested asynchronous context manager is to await the __aenter__
and __aexit__
methods of a nested async context manager from your own such methods (and perhaps pass along the exception information):
class MySession:
def __init__(self):
self.session = None
async def __aenter__(self):
self.session = aiohttp.ClientSession()
await self.session.__aenter__()
return self
async def __aexit__(self, exc_type, exc_val, exc_tb):
if self.session:
return await self.session.__aexit__(exc_type, exc_val, exc_tb)
Technically speaking, you should first assure that there is an actual __aexit__
attribute before entering a nested context manager:
class MySession:
def __init__(self):
self.session = None
self._session_aexit = None
async def __aenter__(self):
self.session = aiohttp.ClientSession()
self._session_aexit = type(self.session).__aexit__
await self.session.__aenter__()
return self
async def __aexit__(self, exc_type, exc_val, exc_tb):
if self.session:
return await self._session_aexit.__aexit__(
self.session, exc_type, exc_val, exc_tb)
See the official PEP that added the concept.
You can't use with
inside a function and have the context manager remain open, no. The with with aiohttp.ClientSession() as session:
block exits as soon as you use return
to exit the __aenter__
coroutine!
For the specific case, entering a aiohttp.ClientSession()
context manager does nothing but return self
. So for that type, just creating the instance and storing it in self.session
, and awaiting on self.session.close()
suffices here, yes.
The general pattern for a nested asynchronous context manager is to await the __aenter__
and __aexit__
methods of a nested async context manager from your own such methods (and perhaps pass along the exception information):
class MySession:
def __init__(self):
self.session = None
async def __aenter__(self):
self.session = aiohttp.ClientSession()
await self.session.__aenter__()
return self
async def __aexit__(self, exc_type, exc_val, exc_tb):
if self.session:
return await self.session.__aexit__(exc_type, exc_val, exc_tb)
Technically speaking, you should first assure that there is an actual __aexit__
attribute before entering a nested context manager:
class MySession:
def __init__(self):
self.session = None
self._session_aexit = None
async def __aenter__(self):
self.session = aiohttp.ClientSession()
self._session_aexit = type(self.session).__aexit__
await self.session.__aenter__()
return self
async def __aexit__(self, exc_type, exc_val, exc_tb):
if self.session:
return await self._session_aexit.__aexit__(
self.session, exc_type, exc_val, exc_tb)
See the official PEP that added the concept.
edited Nov 9 at 15:25
answered Nov 9 at 15:19
Martijn Pieters♦
692k12923972236
692k12923972236
add a comment |
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53228434%2fnested-async-with-using-aiohttp%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown