Skip to content

Commit b043b50

Browse files
committed
basic boilerplate to prep aiohttp
1 parent 506e288 commit b043b50

File tree

2 files changed

+41
-0
lines changed

2 files changed

+41
-0
lines changed

ipinfo/handler_async.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import os
88
import sys
99

10+
import aiohttp
1011
import requests
1112

1213
from .cache.default import DefaultCache
@@ -41,6 +42,9 @@ def __init__(self, access_token=None, **kwargs):
4142
if "timeout" not in self.request_options:
4243
self.request_options["timeout"] = self.REQUEST_TIMEOUT_DEFAULT
4344

45+
# setup aiohttp
46+
self.httpsess = None
47+
4448
# setup cache
4549
if "cache" in kwargs:
4650
self.cache = kwargs["cache"]
@@ -52,8 +56,34 @@ def __init__(self, access_token=None, **kwargs):
5256
cache_options["ttl"] = self.CACHE_TTL
5357
self.cache = DefaultCache(**cache_options)
5458

59+
async def init(self):
60+
"""
61+
Initializes internal aiohttp connection pool.
62+
63+
This isn't _required_, as the pool is initialized lazily when needed.
64+
But in case you require non-lazy initialization, you may await this.
65+
66+
This is idempotent.
67+
"""
68+
await self._ensure_aiohttp_ready()
69+
70+
async def deinit(self):
71+
"""
72+
Deinitialize the async handler.
73+
74+
This is required in case you need to let go of the memory/state
75+
associated with the async handler in a long-running process.
76+
77+
This is idempotent.
78+
"""
79+
if self.httpsess:
80+
await self.httpsess.close()
81+
self.httpsess = None
82+
5583
async def getDetails(self, ip_address=None):
5684
"""Get details for specified IP address as a Details object."""
85+
self._ensure_aiohttp_ready()
86+
5787
# If the supplied IP address uses the objects defined in the built-in
5888
# module ipaddress, extract the appropriate string notation before
5989
# formatting the URL.
@@ -82,6 +112,8 @@ async def getDetails(self, ip_address=None):
82112

83113
async def getBatchDetails(self, ip_addresses):
84114
"""Get details for a batch of IP addresses at once."""
115+
self._ensure_aiohttp_ready()
116+
85117
result = {}
86118

87119
# Pre-populate with anything we've got in the cache, and keep around
@@ -128,6 +160,11 @@ async def getBatchDetails(self, ip_addresses):
128160

129161
return result
130162

163+
def _ensure_aiohttp_ready(self):
164+
"""Ensures aiohttp internal state is initialized."""
165+
if not self.httpsess:
166+
self.httpsess = aiohttp.ClientSession()
167+
131168
def _get_headers(self):
132169
"""Built headers for request to IPinfo API."""
133170
headers = {

tests/handler_async_test.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,15 @@ async def test_init():
1313
assert handler.access_token == token
1414
assert isinstance(handler.cache, DefaultCache)
1515
assert "PK" in handler.countries
16+
await handler.deinit()
1617

1718

1819
@pytest.mark.asyncio
1920
async def test_headers():
2021
token = "mytesttoken"
2122
handler = AsyncHandler(token)
2223
headers = handler._get_headers()
24+
await handler.deinit()
2325

2426
assert "user-agent" in headers
2527
assert "accept" in headers
@@ -77,3 +79,5 @@ async def test_get_details():
7779
assert domains["ip"] == "8.8.8.8"
7880
assert domains["total"] == 12988
7981
assert len(domains["domains"]) == 5
82+
83+
await handler.deinit()

0 commit comments

Comments
 (0)