0
# Database Reader
1
2
Local database reader for MaxMind's MMDB (MaxMind Database) format files. The Reader class provides offline IP geolocation queries with support for all MaxMind database types including City, Country, ASN, ISP, Domain, Connection-Type, Anonymous IP, Anonymous Plus, and Enterprise databases.
3
4
```python
5
import os
6
from collections.abc import Sequence
7
from typing import IO, AnyStr, Optional, Union
8
9
import maxminddb
10
11
from geoip2.models import (
12
ASN, ISP, AnonymousIP, AnonymousPlus, City, ConnectionType,
13
Country, Domain, Enterprise
14
)
15
from geoip2.types import IPAddress
16
```
17
18
## Capabilities
19
20
### Database Reader
21
22
The Reader class provides high-performance local database lookups without requiring network connectivity.
23
24
```python { .api }
25
class Reader:
26
def __init__(self, fileish: Union[AnyStr, int, os.PathLike, IO],
27
locales: Optional[Sequence[str]] = None, mode: int = MODE_AUTO):
28
"""
29
Create a GeoIP2 database reader.
30
31
Parameters:
32
- fileish: Path to MMDB file, file descriptor, or file-like object
33
- locales: List of locale codes for name properties (default: ['en'])
34
Valid codes: 'de', 'en', 'es', 'fr', 'ja', 'pt-BR', 'ru', 'zh-CN'
35
- mode: Database access mode (default: MODE_AUTO)
36
"""
37
38
def city(self, ip_address: IPAddress) -> City:
39
"""
40
Get City object for the IP address from City or Enterprise database.
41
42
Parameters:
43
- ip_address: IPv4 or IPv6 address as string
44
45
Returns:
46
City model object with geographic data including city, country, subdivisions
47
48
Raises:
49
- AddressNotFoundError: IP address not found in database
50
- TypeError: Database type doesn't support city lookups
51
"""
52
53
def country(self, ip_address: IPAddress) -> Country:
54
"""
55
Get Country object for the IP address from Country, City, or Enterprise database.
56
57
Parameters:
58
- ip_address: IPv4 or IPv6 address as string
59
60
Returns:
61
Country model object with country-level geographic data
62
63
Raises:
64
- AddressNotFoundError: IP address not found in database
65
- TypeError: Database type doesn't support country lookups
66
"""
67
68
def asn(self, ip_address: IPAddress) -> ASN:
69
"""
70
Get ASN object for the IP address from ASN database.
71
72
Parameters:
73
- ip_address: IPv4 or IPv6 address as string
74
75
Returns:
76
ASN model object with autonomous system information
77
78
Raises:
79
- AddressNotFoundError: IP address not found in database
80
- TypeError: Database type doesn't support ASN lookups
81
"""
82
83
def isp(self, ip_address: IPAddress) -> ISP:
84
"""
85
Get ISP object for the IP address from ISP database.
86
87
Parameters:
88
- ip_address: IPv4 or IPv6 address as string
89
90
Returns:
91
ISP model object with ISP and organization information
92
93
Raises:
94
- AddressNotFoundError: IP address not found in database
95
- TypeError: Database type doesn't support ISP lookups
96
"""
97
98
def anonymous_ip(self, ip_address: IPAddress) -> AnonymousIP:
99
"""
100
Get AnonymousIP object for the IP address from Anonymous IP database.
101
102
Parameters:
103
- ip_address: IPv4 or IPv6 address as string
104
105
Returns:
106
AnonymousIP model object with anonymity indicators
107
108
Raises:
109
- AddressNotFoundError: IP address not found in database
110
- TypeError: Database type doesn't support anonymous IP lookups
111
"""
112
113
def anonymous_plus(self, ip_address: IPAddress) -> AnonymousPlus:
114
"""
115
Get AnonymousPlus object for the IP address from Anonymous Plus database.
116
117
Parameters:
118
- ip_address: IPv4 or IPv6 address as string
119
120
Returns:
121
AnonymousPlus model object with enhanced anonymity information
122
123
Raises:
124
- AddressNotFoundError: IP address not found in database
125
- TypeError: Database type doesn't support anonymous plus lookups
126
"""
127
128
def connection_type(self, ip_address: IPAddress) -> ConnectionType:
129
"""
130
Get ConnectionType object for the IP address from Connection-Type database.
131
132
Parameters:
133
- ip_address: IPv4 or IPv6 address as string
134
135
Returns:
136
ConnectionType model object with connection type information
137
138
Raises:
139
- AddressNotFoundError: IP address not found in database
140
- TypeError: Database type doesn't support connection type lookups
141
"""
142
143
def domain(self, ip_address: IPAddress) -> Domain:
144
"""
145
Get Domain object for the IP address from Domain database.
146
147
Parameters:
148
- ip_address: IPv4 or IPv6 address as string
149
150
Returns:
151
Domain model object with domain information
152
153
Raises:
154
- AddressNotFoundError: IP address not found in database
155
- TypeError: Database type doesn't support domain lookups
156
"""
157
158
def enterprise(self, ip_address: IPAddress) -> Enterprise:
159
"""
160
Get Enterprise object for the IP address from Enterprise database.
161
162
Parameters:
163
- ip_address: IPv4 or IPv6 address as string
164
165
Returns:
166
Enterprise model object with comprehensive geographic and network data
167
168
Raises:
169
- AddressNotFoundError: IP address not found in database
170
- TypeError: Database type doesn't support enterprise lookups
171
"""
172
173
def metadata(self) -> maxminddb.reader.Metadata:
174
"""
175
Get metadata for the open database.
176
177
Returns:
178
Metadata object containing database information including build time,
179
database type, IP version, record size, and node count
180
"""
181
182
def close(self):
183
"""Close the GeoIP2 database and free resources."""
184
185
def __enter__(self) -> "Reader": ...
186
def __exit__(self, exc_type, exc_value, traceback): ...
187
```
188
189
### Database Access Modes
190
191
Constants for controlling how the database is accessed, providing trade-offs between performance and memory usage.
192
193
```python { .api }
194
from geoip2.database import (
195
MODE_AUTO, MODE_FD, MODE_FILE, MODE_MEMORY, MODE_MMAP, MODE_MMAP_EXT
196
)
197
198
MODE_AUTO: int # Try MODE_MMAP_EXT, MODE_MMAP, MODE_FILE in order (default)
199
MODE_FD: int # fileish parameter is file descriptor, use MODE_MEMORY
200
MODE_FILE: int # Read database as standard file (pure Python)
201
MODE_MEMORY: int # Load entire database into memory (pure Python)
202
MODE_MMAP: int # Memory map database file (pure Python)
203
MODE_MMAP_EXT: int # Memory map with C extension (fastest performance)
204
```
205
206
## Usage Examples
207
208
### Basic Database Usage
209
210
```python
211
import geoip2.database
212
213
# City database lookup
214
with geoip2.database.Reader('/path/to/GeoLite2-City.mmdb') as reader:
215
response = reader.city('203.0.113.0')
216
217
print(f"Country: {response.country.name}")
218
print(f"City: {response.city.name}")
219
print(f"Coordinates: {response.location.latitude}, {response.location.longitude}")
220
print(f"Postal: {response.postal.code}")
221
print(f"Subdivision: {response.subdivisions.most_specific.name}")
222
```
223
224
### ASN Database Usage
225
226
```python
227
with geoip2.database.Reader('/path/to/GeoLite2-ASN.mmdb') as reader:
228
response = reader.asn('203.0.113.0')
229
230
print(f"ASN: {response.autonomous_system_number}")
231
print(f"Organization: {response.autonomous_system_organization}")
232
print(f"Network: {response.network}")
233
```
234
235
### Anonymous IP Database Usage
236
237
```python
238
with geoip2.database.Reader('/path/to/GeoIP2-Anonymous-IP.mmdb') as reader:
239
response = reader.anonymous_ip('203.0.113.0')
240
241
print(f"Is Anonymous: {response.is_anonymous}")
242
print(f"Is VPN: {response.is_anonymous_vpn}")
243
print(f"Is Tor: {response.is_tor_exit_node}")
244
print(f"Is Hosting Provider: {response.is_hosting_provider}")
245
```
246
247
### Anonymous Plus Database Usage
248
249
```python
250
with geoip2.database.Reader('/path/to/GeoIP-Anonymous-Plus.mmdb') as reader:
251
response = reader.anonymous_plus('203.0.113.0')
252
253
print(f"Anonymizer Confidence: {response.anonymizer_confidence}")
254
print(f"Is Anonymous: {response.is_anonymous}")
255
print(f"Is VPN: {response.is_anonymous_vpn}")
256
print(f"Is Tor: {response.is_tor_exit_node}")
257
print(f"Network Last Seen: {response.network_last_seen}")
258
print(f"Provider Name: {response.provider_name}")
259
```
260
261
### Connection Type Database Usage
262
263
```python
264
with geoip2.database.Reader('/path/to/GeoIP2-Connection-Type.mmdb') as reader:
265
response = reader.connection_type('203.0.113.0')
266
267
print(f"Connection Type: {response.connection_type}") # 'Corporate', 'Cable/DSL', etc.
268
```
269
270
### ISP Database Usage
271
272
```python
273
with geoip2.database.Reader('/path/to/GeoIP2-ISP.mmdb') as reader:
274
response = reader.isp('203.0.113.0')
275
276
print(f"ISP: {response.isp}")
277
print(f"Organization: {response.organization}")
278
print(f"ASN: {response.autonomous_system_number}")
279
print(f"Mobile Country Code: {response.mobile_country_code}")
280
```
281
282
### Domain Database Usage
283
284
```python
285
with geoip2.database.Reader('/path/to/GeoIP2-Domain.mmdb') as reader:
286
response = reader.domain('203.0.113.0')
287
288
print(f"Domain: {response.domain}")
289
```
290
291
### Enterprise Database Usage
292
293
```python
294
with geoip2.database.Reader('/path/to/GeoIP2-Enterprise.mmdb') as reader:
295
response = reader.enterprise('203.0.113.0')
296
297
# Enterprise includes all city data plus confidence scores
298
print(f"Country: {response.country.name} (confidence: {response.country.confidence})")
299
print(f"City: {response.city.name} (confidence: {response.city.confidence})")
300
print(f"Subdivision: {response.subdivisions.most_specific.name} (confidence: {response.subdivisions.most_specific.confidence})")
301
```
302
303
### Custom Locales and Access Mode
304
305
```python
306
# Use German with English fallback, memory-mapped access
307
with geoip2.database.Reader(
308
'/path/to/GeoLite2-City.mmdb',
309
locales=['de', 'en'],
310
mode=geoip2.database.MODE_MMAP
311
) as reader:
312
response = reader.city('203.0.113.0')
313
print(response.country.name) # German name if available
314
```
315
316
### Database Metadata
317
318
```python
319
with geoip2.database.Reader('/path/to/GeoLite2-City.mmdb') as reader:
320
metadata = reader.metadata()
321
322
print(f"Database Type: {metadata.database_type}")
323
print(f"Build Date: {metadata.build_epoch}")
324
print(f"IP Version: {metadata.ip_version}")
325
print(f"Record Size: {metadata.record_size}")
326
```
327
328
### Efficient Subnet Enumeration
329
330
```python
331
import geoip2.database
332
import geoip2.errors
333
import ipaddress
334
335
# Efficiently enumerate entire subnets using AddressNotFoundError.network
336
with geoip2.database.Reader('/path/to/GeoLite2-ASN.mmdb') as reader:
337
network = ipaddress.ip_network("192.128.0.0/15")
338
339
ip_address = network[0]
340
while ip_address in network:
341
try:
342
response = reader.asn(ip_address)
343
response_network = response.network
344
print(f"{response_network}: ASN {response.autonomous_system_number}")
345
except geoip2.errors.AddressNotFoundError as e:
346
response_network = e.network
347
print(f"{response_network}: No data")
348
349
# Move to next subnet
350
ip_address = response_network[-1] + 1
351
```
352
353
### Error Handling
354
355
```python
356
import geoip2.database
357
from geoip2.errors import AddressNotFoundError
358
359
try:
360
with geoip2.database.Reader('/path/to/GeoLite2-City.mmdb') as reader:
361
response = reader.city('127.0.0.1') # Private IP
362
except AddressNotFoundError as e:
363
print(f"Address {e.ip_address} not found")
364
print(f"Largest network with no data: {e.network}")
365
except FileNotFoundError:
366
print("Database file not found")
367
except PermissionError:
368
print("Permission denied accessing database file")
369
```
370
371
## Types
372
373
```python { .api }
374
IPAddress = Union[str, IPv6Address, IPv4Address]
375
```