0
# Asynchronous Handlers
1
2
Asynchronous API clients for IP geolocation lookups using aiohttp. Provides concurrent IP lookups with both Core API and Lite API access, advanced timeout controls, and efficient batch processing.
3
4
## Capabilities
5
6
### Async Handler Factory Functions
7
8
Factory functions that create and return configured asynchronous handler instances.
9
10
```python { .api }
11
def getHandlerAsync(access_token=None, **kwargs):
12
"""
13
Create and return asynchronous Handler object for Core API access.
14
15
Parameters:
16
- access_token (str, optional): IPinfo API access token
17
- **kwargs: Additional configuration options
18
19
Returns:
20
AsyncHandler: Configured AsyncHandler instance
21
"""
22
23
def getHandlerAsyncLite(access_token=None, **kwargs):
24
"""
25
Create and return asynchronous HandlerLite object for Lite API access.
26
27
Parameters:
28
- access_token (str, optional): IPinfo API access token
29
- **kwargs: Additional configuration options
30
31
Returns:
32
AsyncHandlerLite: Configured AsyncHandlerLite instance
33
"""
34
```
35
36
### Async Core API Handler
37
38
Asynchronous client for the IPinfo Core API supporting concurrent IP lookups, batch operations with configurable concurrency levels, and advanced timeout management.
39
40
```python { .api }
41
class AsyncHandler:
42
def __init__(self, access_token=None, **kwargs):
43
"""
44
Initialize AsyncHandler with configuration options.
45
46
Parameters:
47
- access_token (str, optional): IPinfo API access token
48
- countries (dict, optional): Custom country code to name mappings
49
- eu_countries (list, optional): Custom list of EU country codes
50
- countries_flags (dict, optional): Custom country flag mappings
51
- countries_currencies (dict, optional): Custom country currency mappings
52
- continent (dict, optional): Custom continent mappings
53
- request_options (dict, optional): HTTP request configuration
54
- cache_options (dict, optional): Cache configuration (maxsize, ttl)
55
- cache (CacheInterface, optional): Custom cache implementation
56
- headers (dict, optional): Custom HTTP headers
57
"""
58
59
async def init(self):
60
"""
61
Initialize internal aiohttp connection pool.
62
63
This is optional as the pool is initialized lazily when needed,
64
but can be used for non-lazy initialization.
65
"""
66
67
async def deinit(self):
68
"""
69
Deinitialize the async handler and cleanup resources.
70
71
Required for proper resource cleanup in long-running processes.
72
Must be called to close aiohttp session.
73
"""
74
75
async def getDetails(self, ip_address=None, timeout=None):
76
"""
77
Get details for specified IP address asynchronously.
78
79
Parameters:
80
- ip_address (str|IPv4Address|IPv6Address, optional): IP address to lookup
81
- timeout (int, optional): Request timeout override
82
83
Returns:
84
Details: IP address details object
85
86
Raises:
87
RequestQuotaExceededError: When API quota exceeded
88
APIError: When API returns error response
89
"""
90
91
async def getBatchDetails(self, ip_addresses, batch_size=None, timeout_per_batch=5, timeout_total=None, raise_on_fail=True):
92
"""
93
Get details for multiple IP addresses with concurrent batch processing.
94
95
Parameters:
96
- ip_addresses (list): List of IP addresses to lookup
97
- batch_size (int, optional): Batch size (default: 1000, max: 1000)
98
- timeout_per_batch (int, optional): Timeout per batch request (default: 5)
99
- timeout_total (int, optional): Total operation timeout
100
- raise_on_fail (bool, optional): Whether to raise on errors (default: True)
101
102
Returns:
103
dict: Mapping of IP addresses to Details objects or error info
104
105
Raises:
106
RequestQuotaExceededError: When API quota exceeded
107
TimeoutExceededError: When timeout limits exceeded
108
"""
109
110
async def getBatchDetailsIter(self, ip_addresses, batch_size=None, raise_on_fail=True):
111
"""
112
Async iterator for batch details lookup.
113
114
Parameters:
115
- ip_addresses (list): List of IP addresses to lookup
116
- batch_size (int, optional): Batch size (default: 1000)
117
- raise_on_fail (bool, optional): Whether to raise on errors (default: True)
118
119
Yields:
120
tuple: (ip_address, details) pairs
121
122
Raises:
123
RequestQuotaExceededError: When API quota exceeded
124
"""
125
```
126
127
### Async Lite API Handler
128
129
Asynchronous client for the IPinfo Lite API providing fast, concurrent IP geolocation lookups with simplified response data.
130
131
```python { .api }
132
class AsyncHandlerLite:
133
def __init__(self, access_token=None, **kwargs):
134
"""
135
Initialize AsyncHandlerLite with configuration options.
136
137
Parameters: Same as AsyncHandler class
138
"""
139
140
async def init(self):
141
"""
142
Initialize internal aiohttp connection pool.
143
144
Optional lazy initialization for connection pool.
145
"""
146
147
async def deinit(self):
148
"""
149
Deinitialize the async handler and cleanup resources.
150
151
Required for proper resource cleanup.
152
"""
153
154
async def getDetails(self, ip_address=None, timeout=None):
155
"""
156
Get details for specified IP address using Lite API asynchronously.
157
158
Parameters:
159
- ip_address (str|IPv4Address|IPv6Address, optional): IP address to lookup
160
- timeout (int, optional): Request timeout override
161
162
Returns:
163
Details: IP address details object with Lite API fields
164
165
Raises:
166
RequestQuotaExceededError: When API quota exceeded
167
APIError: When API returns error response
168
"""
169
```
170
171
## Usage Examples
172
173
### Basic Async Usage
174
175
```python
176
import asyncio
177
import ipinfo
178
179
async def main():
180
# Create async handler
181
handler = ipinfo.getHandlerAsync('your_access_token')
182
183
try:
184
# Single IP lookup
185
details = await handler.getDetails('8.8.8.8')
186
print(f"Location: {details.city}, {details.region}, {details.country}")
187
print(f"ISP: {details.org}")
188
finally:
189
# Always cleanup resources
190
await handler.deinit()
191
192
# Run the async function
193
asyncio.run(main())
194
```
195
196
### Concurrent Lookups
197
198
```python
199
import asyncio
200
import ipinfo
201
202
async def lookup_ip(handler, ip):
203
"""Lookup single IP with error handling"""
204
try:
205
details = await handler.getDetails(ip)
206
return ip, details.city, details.country
207
except Exception as e:
208
return ip, None, str(e)
209
210
async def main():
211
handler = ipinfo.getHandlerAsync('your_access_token')
212
213
try:
214
# Concurrent individual lookups
215
ips = ['8.8.8.8', '1.1.1.1', '208.67.222.222']
216
tasks = [lookup_ip(handler, ip) for ip in ips]
217
results = await asyncio.gather(*tasks)
218
219
for ip, city, country in results:
220
print(f"{ip}: {city}, {country}")
221
finally:
222
await handler.deinit()
223
224
asyncio.run(main())
225
```
226
227
### Batch Processing
228
229
```python
230
import asyncio
231
import ipinfo
232
233
async def main():
234
handler = ipinfo.getHandlerAsync('your_access_token')
235
236
try:
237
# Efficient batch processing
238
ips = ['8.8.8.8', '1.1.1.1', '208.67.222.222'] * 100
239
results = await handler.getBatchDetails(
240
ips,
241
batch_size=50,
242
timeout_per_batch=10,
243
timeout_total=60
244
)
245
246
print(f"Processed {len(results)} IPs")
247
for ip, details in results.items():
248
if hasattr(details, 'city'):
249
print(f"{ip}: {details.city}")
250
finally:
251
await handler.deinit()
252
253
asyncio.run(main())
254
```
255
256
### Context Manager Pattern
257
258
```python
259
import asyncio
260
import ipinfo
261
from contextlib import asynccontextmanager
262
263
@asynccontextmanager
264
async def ipinfo_handler(access_token):
265
"""Context manager for proper resource management"""
266
handler = ipinfo.getHandlerAsync(access_token)
267
await handler.init()
268
try:
269
yield handler
270
finally:
271
await handler.deinit()
272
273
async def main():
274
async with ipinfo_handler('your_access_token') as handler:
275
details = await handler.getDetails('8.8.8.8')
276
print(f"City: {details.city}")
277
278
asyncio.run(main())
279
```
280
281
### Async Iterator Usage
282
283
```python
284
import asyncio
285
import ipinfo
286
287
async def main():
288
handler = ipinfo.getHandlerAsync('your_access_token')
289
290
try:
291
ips = ['8.8.8.8', '1.1.1.1', '208.67.222.222'] * 10
292
293
async for ip, details in handler.getBatchDetailsIter(ips, batch_size=10):
294
if hasattr(details, 'city'):
295
print(f"{ip}: {details.city}, {details.country}")
296
finally:
297
await handler.deinit()
298
299
asyncio.run(main())
300
```
301
302
### Lite API Async Usage
303
304
```python
305
import asyncio
306
import ipinfo
307
308
async def main():
309
handler = ipinfo.getHandlerAsyncLite('your_access_token')
310
311
try:
312
details = await handler.getDetails('8.8.8.8')
313
print(f"Country: {details.country}")
314
print(f"Country Code: {details.country_code}")
315
finally:
316
await handler.deinit()
317
318
asyncio.run(main())
319
```
320
321
### Error Handling
322
323
```python
324
import asyncio
325
import ipinfo
326
from ipinfo.exceptions import RequestQuotaExceededError, TimeoutExceededError
327
from ipinfo.error import APIError
328
329
async def main():
330
handler = ipinfo.getHandlerAsync('your_access_token')
331
332
try:
333
details = await handler.getDetails('8.8.8.8')
334
print(details.city)
335
except RequestQuotaExceededError:
336
print("Monthly quota exceeded")
337
except TimeoutExceededError:
338
print("Request timed out")
339
except APIError as e:
340
print(f"API error {e.error_code}: {e.error_json}")
341
except Exception as e:
342
print(f"Unexpected error: {e}")
343
finally:
344
await handler.deinit()
345
346
asyncio.run(main())
347
```
348
349
## Types
350
351
```python { .api }
352
# Async handler configuration (same as sync handlers)
353
AsyncHandlerOptions = {
354
'countries': dict,
355
'eu_countries': list,
356
'countries_flags': dict,
357
'countries_currencies': dict,
358
'continent': dict,
359
'request_options': dict,
360
'cache_options': dict,
361
'cache': CacheInterface,
362
'headers': dict
363
}
364
365
# Async batch result
366
AsyncBatchResult = dict # IP address -> Details object or error info
367
368
# Async iterator result
369
AsyncIterResult = tuple # (ip_address, details)
370
```