Skip to content

Commit 32eb961

Browse files
committed
Adding async function
1 parent ee5cc2a commit 32eb961

File tree

2 files changed

+93
-1
lines changed

2 files changed

+93
-1
lines changed

ipinfo/handler_async.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,3 +347,69 @@ def _ensure_aiohttp_ready(self):
347347

348348
timeout = aiohttp.ClientTimeout(total=self.request_options["timeout"])
349349
self.httpsess = aiohttp.ClientSession(timeout=timeout)
350+
351+
async def getIterativeBatchDetails(
352+
self,
353+
ip_addresses,
354+
batch_size=None,
355+
raise_on_fail=True,
356+
):
357+
if batch_size is None:
358+
batch_size = BATCH_MAX_SIZE
359+
360+
results = {}
361+
362+
lookup_addresses = []
363+
for ip_address in ip_addresses:
364+
if isinstance(ip_address, IPv4Address) or isinstance(
365+
ip_address, IPv6Address
366+
):
367+
ip_address = ip_address.exploded
368+
369+
if ip_address and is_bogon(ip_address):
370+
details = {}
371+
details["ip"] = ip_address
372+
details["bogon"] = True
373+
yield Details(details)
374+
375+
try:
376+
cached_ipaddr = self.cache[cache_key(ip_address)]
377+
results[ip_address] = cached_ipaddr
378+
except KeyError:
379+
lookup_addresses.append(ip_address)
380+
381+
if len(lookup_addresses) == 0:
382+
yield results.items()
383+
384+
url = API_URL + "/batch"
385+
headers = handler_utils.get_headers(self.access_token, self.headers)
386+
headers["content-type"] = "application/json"
387+
388+
async def process_batch(batch):
389+
try:
390+
async with aiohttp.ClientSession(headers=headers) as session:
391+
response = await session.post(url, json=batch)
392+
response.raise_for_status()
393+
json_response = await response.json()
394+
for ip_address, details in json_response.items():
395+
self.cache[cache_key(ip_address)] = details
396+
results[ip_address] = details
397+
398+
except Exception as e:
399+
return handler_utils.return_or_fail(raise_on_fail, e, results)
400+
401+
for i in range(0, len(lookup_addresses), batch_size):
402+
batch = lookup_addresses[i : i + batch_size]
403+
await process_batch(batch)
404+
405+
for ip_address, details in results.items():
406+
if isinstance(details, dict):
407+
handler_utils.format_details(
408+
details,
409+
self.countries,
410+
self.eu_countries,
411+
self.countries_flags,
412+
self.countries_currencies,
413+
self.continents,
414+
)
415+
yield ip_address, details

tests/handler_async_test.py

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,8 @@ async def test_get_details():
113113

114114
def _prepare_batch_test():
115115
"""Helper for preparing batch test cases."""
116-
token = os.environ.get("IPINFO_TOKEN", "")
116+
token = "godmode666"
117+
# os.environ.get("IPINFO_TOKEN", "")
117118
if not token:
118119
pytest.skip("token required for batch tests")
119120
handler = AsyncHandler(token)
@@ -145,6 +146,31 @@ async def test_get_batch_details(batch_size):
145146
await handler.deinit()
146147

147148

149+
def _check_iterative_batch_details(ip, details, token):
150+
"""Helper for iterative batch tests."""
151+
assert ip == details.get("ip")
152+
assert "country" in details
153+
assert "city" in details
154+
if token:
155+
assert "asn" in details or "anycast" in details
156+
assert "company" in details or "org" in details
157+
assert "privacy" in details or "anycast" in details
158+
assert "abuse" in details or "anycast" in details
159+
assert "domains" in details or "anycast" in details
160+
161+
162+
@pytest.mark.parametrize("batch_size", [None, 1, 2, 3])
163+
@pytest.mark.asyncio
164+
async def test_get_iterative_batch_details(batch_size):
165+
handler, token, ips = _prepare_batch_test()
166+
async for ips, details in handler.getIterativeBatchDetails(
167+
ips, batch_size
168+
):
169+
# results.append((ip_address, details))
170+
_check_iterative_batch_details(ips, details, token)
171+
await handler.deinit()
172+
173+
148174
@pytest.mark.parametrize("batch_size", [None, 1, 2, 3])
149175
@pytest.mark.asyncio
150176
async def test_get_batch_details_total_timeout(batch_size):

0 commit comments

Comments
 (0)