Skip to content

Commit d2f56b0

Browse files
committed
fix: aiohttp.ClientSession needs to be created inside an async function
1 parent ef1f77d commit d2f56b0

File tree

2 files changed

+40
-25
lines changed

2 files changed

+40
-25
lines changed

src/aleph/sdk/client/http.py

+37-22
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030

3131
class AlephHttpClient(AlephClient):
3232
api_server: str
33-
http_session: aiohttp.ClientSession
33+
_http_session: Optional[aiohttp.ClientSession]
3434

3535
def __init__(
3636
self,
@@ -48,35 +48,50 @@ def __init__(
4848
if not self.api_server:
4949
raise ValueError("Missing API host")
5050

51-
connector: Union[aiohttp.BaseConnector, None]
51+
self.connector: Union[aiohttp.BaseConnector, None]
5252
unix_socket_path = api_unix_socket or settings.API_UNIX_SOCKET
53+
5354
if ssl_context:
54-
connector = aiohttp.TCPConnector(ssl=ssl_context)
55+
self.connector = aiohttp.TCPConnector(ssl=ssl_context)
5556
elif unix_socket_path and allow_unix_sockets:
5657
check_unix_socket_valid(unix_socket_path)
57-
connector = aiohttp.UnixConnector(path=unix_socket_path)
58+
self.connector = aiohttp.UnixConnector(path=unix_socket_path)
5859
else:
59-
connector = None
60-
61-
# ClientSession timeout defaults to a private sentinel object and may not be None.
62-
self.http_session = (
63-
aiohttp.ClientSession(
64-
base_url=self.api_server,
65-
connector=connector,
66-
timeout=timeout,
67-
json_serialize=extended_json_encoder,
68-
)
69-
if timeout
70-
else aiohttp.ClientSession(
71-
base_url=self.api_server,
72-
connector=connector,
73-
json_serialize=lambda obj: json.dumps(
74-
obj, default=extended_json_encoder
75-
),
60+
self.connector = None
61+
62+
self.timeout = timeout
63+
self._http_session = None
64+
65+
@property
66+
def http_session(self) -> aiohttp.ClientSession:
67+
if self._http_session is None:
68+
raise Exception(
69+
f"{self.__class__.__name__} can only be using within an async context manager.\n\n"
70+
"Please use it this way:\n\n"
71+
" async with {self.__class__.__name__}(...) as client:"
7672
)
77-
)
73+
74+
return self._http_session
7875

7976
async def __aenter__(self) -> "AlephHttpClient":
77+
if self._http_session is None:
78+
self._http_session = (
79+
aiohttp.ClientSession(
80+
base_url=self.api_server,
81+
connector=self.connector,
82+
timeout=self.timeout,
83+
json_serialize=extended_json_encoder,
84+
)
85+
if self.timeout
86+
else aiohttp.ClientSession(
87+
base_url=self.api_server,
88+
connector=self.connector,
89+
json_serialize=lambda obj: json.dumps(
90+
obj, default=extended_json_encoder
91+
),
92+
)
93+
)
94+
8095
return self
8196

8297
async def __aexit__(self, exc_type, exc_val, exc_tb):

tests/unit/conftest.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ def mock_session_with_post_success(
193193
client = AuthenticatedAlephHttpClient(
194194
account=ethereum_account, api_server="http://localhost"
195195
)
196-
client.http_session = http_session
196+
client._http_session = http_session
197197

198198
return client
199199

@@ -254,7 +254,7 @@ def get(self, *_args, **_kwargs):
254254
http_session = MockHttpSession()
255255

256256
client = AlephHttpClient(api_server="http://localhost")
257-
client.http_session = http_session
257+
client._http_session = http_session
258258

259259
return client
260260

@@ -281,6 +281,6 @@ def post(self, *_args, **_kwargs):
281281
client = AuthenticatedAlephHttpClient(
282282
account=ethereum_account, api_server="http://localhost"
283283
)
284-
client.http_session = http_session
284+
client._http_session = http_session
285285

286286
return client

0 commit comments

Comments
 (0)