### Basic MaxMind DB lookup example Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/docs/index.md Demonstrates how to open a MaxMind DB file and perform lookups for an IP address using get() and get_with_prefix_len(). Iterating over the database is also shown. ```python import maxminddb with maxminddb.open_database('GeoLite2-City.mmdb') as reader: reader.get('152.216.7.110') reader.get_with_prefix_len('152.216.7.110') for network, record in reader: ... ``` -------------------------------- ### Minimal Example Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/QUICK_START.md This example demonstrates how to open a MaxMind DB file and perform a basic IP address lookup. ```APIDOC ## Minimal Example This example demonstrates how to open a MaxMind DB file and perform a basic IP address lookup. ```python import maxminddb # Open database with default mode (auto-selects best available) with maxminddb.open_database('GeoLite2-City.mmdb') as reader: # Look up an IP address result = reader.get('152.216.7.110') print(result) # {'country': {...}, 'city': {...}, ...} ``` ``` -------------------------------- ### Install maxminddb from source Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/README.rst Install the maxminddb package from the source directory using pip. This is an alternative installation method if PyPI is not accessible. ```bash python -m pip install . ``` -------------------------------- ### Install maxminddb using pip Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/README.rst Install the maxminddb package from PyPI. This command installs the package and attempts to build the C extension. ```bash pip install maxminddb ``` -------------------------------- ### Minimal Example: Open Database and Lookup IP Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/QUICK_START.md This is the most basic example of how to open a MaxMind DB file and perform an IP address lookup. It uses the default mode for opening the database, which automatically selects the best available access method. Ensure you have a 'GeoLite2-City.mmdb' file in the same directory or provide the correct path. ```python import maxminddb # Open database with default mode (auto-selects best available) with maxminddb.open_database('GeoLite2-City.mmdb') as reader: # Look up an IP address result = reader.get('152.216.7.110') print(result) # {'country': {...}, 'city': {...}, ...} ``` -------------------------------- ### Force Extension Build During Installation Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/api-reference/extension.md Installs the maxminddb package, forcing the C extension build and failing if it cannot be built. Use this to guarantee the extension is present. ```bash MAXMINDDB_REQUIRE_EXTENSION=1 pip install maxminddb ``` -------------------------------- ### Install Using System libmaxminddb Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/api-reference/extension.md Installs the maxminddb package, utilizing a system-installed libmaxminddb library. This is useful if you have libmaxminddb pre-installed and want to link against it. ```bash MAXMINDDB_USE_SYSTEM_LIBMAXMINDDB=1 pip install maxminddb ``` -------------------------------- ### Install MaxMind DB with C Extension Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/QUICK_START.md Install the maxminddb package, forcing the compilation of the C extension. This is required for certain modes like MODE_MMAP_EXT. ```bash pip install maxminddb --no-binary maxminddb ``` -------------------------------- ### Basic IP Lookup Example Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/README.md Demonstrates how to open a MaxMind DB file and perform a basic IP address lookup to retrieve country information. Ensure the database file exists and is accessible. ```python import maxminddb with maxminddb.open_database('GeoLite2-City.mmdb') as reader: result = reader.get('152.216.7.110') if result: print(f"Country: {result['country']['names']['en']}") ``` -------------------------------- ### Example Usage of Decoder.decode Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/api-reference/decoder-class.md Demonstrates how to use the Decoder class to read data from a buffer. Note that Decoder is typically used internally by the Reader class. ```python from maxminddb.decoder import Decoder # Decoder is typically not used directly; it's internal to Reader # This is shown for documentation purposes # Create decoder from buffer decoder = Decoder(buffer, pointer_base=1024) # Decode a value starting at offset 0 value, next_offset = decoder.decode(0) print(f"Decoded: {value}") print(f"Next offset: {next_offset}") # Recursively decode multiple values offset = 0 values = [] for _ in range(10): value, offset = decoder.decode(offset) values.append(value) ``` -------------------------------- ### Example with MODE_FD using integer file descriptor Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/api-reference/modes.md Shows how to open a MaxMind DB database using MODE_FD with an integer file descriptor. The caller is responsible for closing the file descriptor. ```python import os import maxminddb # Using with integer file descriptor fd = os.open('GeoLite2-City.mmdb', os.O_RDONLY) try: reader = maxminddb.open_database(fd, maxminddb.MODE_FD) result = reader.get('1.2.3.4') reader.close() finally: os.close(fd) # Caller closes the fd ``` -------------------------------- ### Open Database and Lookup IP Address Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/00_START_HERE.md This is the simplest way to use the library. Import the library, open a MaxMind DB file using a context manager, and then use the get() method to look up an IP address. The result can be accessed like a dictionary. ```python import maxminddb # Open database with maxminddb.open_database('GeoLite2-City.mmdb') as reader: # Look up an IP result = reader.get('1.2.3.4') # Use the result if result: print(result['country']['names']['en']) ``` -------------------------------- ### Example with MODE_FD using file descriptor Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/api-reference/modes.md Demonstrates opening a MaxMind DB database using MODE_FD with a file object. The reader does not close the file object, and the caller is responsible for cleanup. ```python import maxminddb # Using with file descriptor with open('GeoLite2-City.mmdb', 'rb') as f: reader = maxminddb.open_database(f, maxminddb.MODE_FD) result = reader.get('1.2.3.4') reader.close() # File 'f' is closed by context manager, not by Reader ``` -------------------------------- ### Lookup IP Address by String Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/QUICK_START.md Performs a lookup for an IP address provided as a string. This is the most straightforward way to get data for a given IP. ```python # By string result = reader.get('1.2.3.4') ``` -------------------------------- ### Data Decoding Flow Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/ARCHITECTURE.md Illustrates the step-by-step process of decoding data within the MaxMind DB format, starting from a pointer and ending with a decoded value. ```text Pointer → Offset in Data Section ↓ Control Byte (type + size info) ↓ Type Decoder Selected ↓ Size Extracted from Control Byte ↓ Appropriate Decoder Function Called ↓ Decoded Value Returned ``` -------------------------------- ### Retrieve Database Metadata Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/README.md Example of accessing metadata associated with the MaxMind DB file, such as the database type, IP version it covers, and supported languages. ```python meta = reader.metadata() print(f"Type: {meta.database_type}") print(f"Version: {meta.ip_version}") print(f"Languages: {meta.languages}") ``` -------------------------------- ### Type Narrowing with MaxMind DB Reader Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/types.md Example demonstrating type narrowing in application code when processing results from the MaxMind DB reader. It shows how to handle 'Record | None' and nested dictionaries. ```python import maxminddb from maxminddb.types import Record, RecordDict with maxminddb.open_database('GeoLite2-City.mmdb') as reader: result: Record | None = reader.get('1.2.3.4') if result is None: print("IP not found") elif isinstance(result, dict): # result is narrowed to RecordDict country: Record = result.get('country') if isinstance(country, dict): names: Record = country.get('names') if isinstance(names, dict): en_name: Record = names.get('en') if isinstance(en_name, str): print(f"Country: {en_name}") ``` -------------------------------- ### Accessing MaxMind DB Python Package Version Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/IMPORTS_GUIDE.md Demonstrates how to get the package version string. You can access it directly via `maxminddb.__version__` or by using `importlib.metadata.version` for parsed version information. ```python import maxminddb # Get version string version = maxminddb.__version__ # "3.1.1" # Parse version if needed from importlib.metadata import version as get_version ver = get_version("maxminddb") # "3.1.1" ``` -------------------------------- ### Get Record and Prefix Length Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/api-reference/reader-class.md The `get_with_prefix_len` method returns both the record for an IP address and the network prefix length. This is useful for determining the network size associated with the IP. ```python import maxminddb from ipaddress import ip_network with maxminddb.open_database('GeoLite2-City.mmdb') as reader: record, prefix_len = reader.get_with_prefix_len('152.216.7.110') if record: print(f"Record: {record}") print(f"Network prefix length: {prefix_len}") # e.g., 24 for a /24 network # Construct the network net = ip_network(('152.216.7.110', prefix_len), strict=False) print(f"Network: {net}") # e.g., 152.216.7.0/24 ``` -------------------------------- ### Read IP address data with maxminddb Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/README.rst Open a MaxMind DB file and perform lookups for IP addresses. Use 'get' for record data or 'get_with_prefix_len' to also retrieve the network prefix length. Iterating over the reader yields network and record pairs. ```python import maxminddb with maxminddb.open_database('GeoLite2-City.mmdb') as reader: reader.get('152.216.7.110') reader.get_with_prefix_len('152.216.7.110') for network, record in reader: ... ``` -------------------------------- ### Get with Prefix Length Function Signature Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/types.md Signature for retrieving a record and its prefix length by IP address. Returns a tuple of (Record or None, prefix length). ```python def get_with_prefix_len( self, ip_address: str | IPv6Address | IPv4Address, ) -> tuple[Record | None, int]: """Return is tuple of (Record or None, prefix length).""" ``` -------------------------------- ### Example Usage of Record Type Aliases Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/types.md Demonstrates how to use the Record type alias to represent various data structures, from simple primitive values to complex nested dictionaries and lists. Ensure imported types are correctly handled. ```python from maxminddb.types import Record # Simple primitive result_1: Record = "United States" result_2: Record = 42 result_3: Record = 3.14 result_4: Record = True result_5: Record = b"bytes" # List of primitives result_6: Record = ["en", "es", "fr"] # Dictionary of mixed types result_7: Record = { "country": { "iso_code": "US", "names": { "en": "United States", "es": "Estados Unidos" } }, "city": { "geoname_id": 5391959, "names": { "en": "San Francisco" } }, "latitude": 37.7749, "longitude": -122.4194, "accuracy_radius": 100 } # Complex nested structure result_8: Record = { "subdivisions": [ { "iso_code": "CA", "names": {"en": "California"} } ], "traits": [True, False, True], "location": { "coordinates": [37.7749, -122.4194] } } ``` -------------------------------- ### Open MaxMind DB Database Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/README.md Use `open_database` to get a Reader instance. Supports various input types like file paths or file-like objects. Defaults to auto-detecting the best mode. ```python def open_database( database: AnyStr | int | PathLike | IO, mode: int = MODE_AUTO, ) -> Reader ``` -------------------------------- ### Get Database Build Epoch Timestamp Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/api-reference/metadata-class.md Retrieves the Unix epoch timestamp indicating when the database was built. Use this to determine the database's age and check for newer versions. Convert to a readable date using `datetime.fromtimestamp`. ```python meta.build_epoch # 1751328000 (example timestamp) # Convert to readable date from datetime import datetime, timezone build_date = datetime.fromtimestamp(meta.build_epoch, tz=timezone.utc) print(build_date) # 2025-10-28 12:00:00+00:00 ``` -------------------------------- ### Perform IP Address Lookup Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/api-reference/reader-class.md Use the `get` method to retrieve the record associated with an IP address. The lookup can be performed using a string representation of the IP address or an `ipaddress` object. Returns None if the IP address is not found. ```python import maxminddb from ipaddress import ip_address with maxminddb.open_database('GeoLite2-City.mmdb') as reader: # Lookup by string record = reader.get('152.216.7.110') if record: print(f"Country: {record.get('country', {}).get('names', {}).get('en')}") # Lookup by IP address object record = reader.get(ip_address('1.2.3.4')) ``` -------------------------------- ### Get Node Count Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/api-reference/metadata-class.md Retrieves the total number of nodes in the search tree. This value is crucial for calculating the start of the data section. ```python meta.node_count # 3862206 # The search tree size can be calculated tree_size = meta.node_count * meta.node_byte_size print(f"Search tree: {tree_size:,} bytes") # ~15,448,824 bytes for typical database ``` -------------------------------- ### Recommended Initialization with Context Manager Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/QUICK_START.md Use the 'with' statement for automatic resource management, ensuring the database reader is properly closed upon exiting the block. This is the recommended approach. ```python # Automatic cleanup with maxminddb.open_database('db.mmdb') as reader: result = reader.get('1.2.3.4') # Reader automatically closed on exit ``` -------------------------------- ### Import Entry Point Function Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/IMPORTS_GUIDE.md Import the `open_database` function for accessing databases. This is the primary entry point for using the library. ```python from maxminddb import open_database ``` ```python reader = maxminddb.open_database('database.mmdb') ``` -------------------------------- ### Decode Method Signature Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/api-reference/decoder-class.md Decodes a value from the database buffer starting at a given offset. ```python def decode(self, offset: int) -> tuple[Record, int] ``` -------------------------------- ### decode Method Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/api-reference/decoder-class.md Decodes a value from the database buffer starting at a specified offset. This is the primary method for retrieving data. ```APIDOC ## Methods ### decode Decodes a value from the database buffer starting at the given offset. ```python def decode(self, offset: int) -> tuple[Record, int] ``` #### Parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `offset` | `int` | Yes | Byte offset in the buffer where decoding should start | #### Return Type `tuple[Record, int]` — A tuple containing: - The decoded value (can be any Record type: primitive, list, or dictionary) - The new offset after the decoded value #### Raises | Error | Condition | |-------|-----------| | `InvalidDatabaseError` | Unknown or unsupported data type encountered, or corrupted data | #### Description The Decoder reads a control byte at the given offset to determine the data type and size. It then decodes the appropriate data structure. Extended types are supported for types 8 and above. This method is the primary decoding interface. It handles all MaxMind DB data types: - **Type 1**: Pointer (to another location in the data section) - **Type 2**: UTF-8 string - **Type 3**: Double (64-bit float) - **Type 4**: Bytes - **Type 5**: Unsigned 16-bit integer (uint16) - **Type 6**: Unsigned 32-bit integer (uint32) - **Type 7**: Map (dictionary) - **Type 8**: Signed 32-bit integer (int32) - **Type 9**: Unsigned 64-bit integer (uint64) - **Type 10**: Unsigned 128-bit integer (uint128) - **Type 11**: Array (list) - **Type 14**: Boolean - **Type 15**: Float (32-bit) #### Example ```python from maxminddb.decoder import Decoder # Decoder is typically not used directly; it's internal to Reader # This is shown for documentation purposes # Create decoder from buffer decoder = Decoder(buffer, pointer_base=1024) # Decode a value starting at offset 0 value, next_offset = decoder.decode(0) print(f"Decoded: {value}") print(f"Next offset: {next_offset}") # Recursively decode multiple values offset = 0 values = [] for _ in range(10): value, offset = decoder.decode(offset) values.append(value) ``` ``` -------------------------------- ### Open Database with String Path Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/QUICK_START.md Demonstrates opening a MaxMind DB file using a simple string path. This is a common way to specify the database file location. ```python import maxminddb # String path reader = maxminddb.open_database('GeoLite2-City.mmdb') ``` -------------------------------- ### Get Record Function Signature Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/types.md Signature for retrieving a record by IP address. Returns a Record or None if the IP is not found. ```python def get(self, ip_address: str | IPv6Address | IPv4Address) -> Record | None: """Return value is a Record or None.""" ``` -------------------------------- ### Get Record Size Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/api-reference/metadata-class.md Retrieves the bit size of each record in the binary search tree. This determines how node bytes are read and interpreted. ```python meta.record_size # 32 # Calculate node size in bytes node_byte_size = meta.record_size // 4 print(f"Each node: {node_byte_size} bytes") # 8 bytes for 32-bit records ``` -------------------------------- ### Open Database with Context Manager Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/api-reference/open-database.md Opens a MaxMind DB file using a context manager for automatic resource management. This is the recommended approach for basic usage. ```python import maxminddb with maxminddb.open_database('GeoLite2-City.mmdb') as reader: result = reader.get('152.216.7.110') print(result) ``` -------------------------------- ### Reader Constructor (C Extension) Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/api-reference/extension.md Initializes the C extension Reader. Only `MODE_AUTO` and `MODE_MMAP_EXT` modes are supported; other modes will raise an error. ```python def __init__( self, database: AnyStr | int | PathLike | IO, mode: int = ..., ) -> None ``` -------------------------------- ### Minimal Imports for Basic Usage Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/IMPORTS_GUIDE.md For straightforward use cases, import the entire maxminddb library and use the open_database function to open a database file. ```python import maxminddb # Everything you need is here with maxminddb.open_database('GeoLite2-City.mmdb') as reader: result = reader.get('1.2.3.4') ``` -------------------------------- ### Checking for and Using C Extension Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/IMPORTS_GUIDE.md This snippet demonstrates how to check if the optional C extension is available and how to use it implicitly with open_database by setting MODE_AUTO. ```python try: from maxminddb import extension has_extension = hasattr(extension, 'Reader') except ImportError: has_extension = False # Use open_database with MODE_AUTO to automatically use extension if available reader = maxminddb.open_database('db.mmdb') # Uses extension if present ``` -------------------------------- ### Get Database Type String Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/api-reference/metadata-class.md Retrieves a string identifier for the database type, such as 'GeoIP2-City' or 'GeoLite2-Country'. This helps in validating the database's purpose before performing lookups. ```python meta.database_type # "GeoLite2-City" # Validate database type if meta.database_type != "GeoLite2-City": raise ValueError(f"Expected GeoLite2-City, got {meta.database_type}") ``` -------------------------------- ### Import Main Package Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/IMPORTS_GUIDE.md Import all primary symbols directly from the main package namespace. ```python import maxminddb ``` -------------------------------- ### Calculate Search Tree Size Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/api-reference/metadata-class.md Calculates the total size of the search tree in bytes. This value, along with a fixed separator, determines the starting offset of the data section. ```python meta.search_tree_size # 30,897,648 # Know where data section starts data_section_start = meta.search_tree_size + 16 # 16-byte separator print(f"Data section starts at byte {data_section_start}") ``` -------------------------------- ### Process Records with RecordList Type Hint Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/types.md Demonstrates how to use the RecordList type hint for function parameters and variables. This improves code readability and allows for static analysis. ```python from maxminddb.types import RecordList # Function accepting a list of records def process_records(records: RecordList) -> None: for record in records: print(record) # Typical use: arrays from database languages: RecordList = ["en", "es", "fr"] subdivisions: RecordList = [ {"iso_code": "CA", "names": {"en": "California"}}, {"iso_code": "OR", "names": {"en": "Oregon"}} ] ``` -------------------------------- ### IP Lookup with Prefix Length Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/README.md Shows how to use `get_with_prefix_len` to retrieve both the record and the network prefix length for a given IP address. Useful for CIDR-based lookups. ```python record, prefix_len = reader.get_with_prefix_len('1.2.3.4') if record: print(f"Network: /{prefix_len}") ``` -------------------------------- ### Get Available Languages List Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/api-reference/metadata-class.md Retrieves a list of ISO 639-1 language codes for which localized data is available in the database. This helps in knowing which languages can be expected in location results. ```python meta.languages # ["en", "es", "fr", "de", "ja", "zh-CN"] # Check if German names available if "de" in meta.languages: # German names will be in result['city']['names']['de'] pass ``` -------------------------------- ### Open Database with PathLike Object Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/QUICK_START.md Shows how to open a MaxMind DB file using a `PathLike` object, such as one created by `pathlib.Path`. This offers more object-oriented path manipulation. ```python import maxminddb from pathlib import Path # PathLike object reader = maxminddb.open_database(Path('db.mmdb')) ``` -------------------------------- ### File Organization Overview Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/INDEX.md This snippet outlines the directory structure for the maxminddb Python package, detailing the purpose of each file and subdirectory. ```text /workspace/home/output/ ├── README.md # Project overview & nav ├── INDEX.md # This file ├── QUICK_START.md # Essential 5-minute reference ├── ARCHITECTURE.md # Internal design & data flow ├── IMPORTS_GUIDE.md # Import patterns & references ├── types.md # Type aliases documentation ├── errors.md # Exception reference └── api-reference/ # API documentation (one per module/class) ├── open-database.md # open_database() function ├── reader-class.md # Reader class ├── metadata-class.md # Metadata dataclass ├── modes.md # Open modes (constants) ├── decoder-class.md # Decoder (internal) └── extension.md # C extension module ``` -------------------------------- ### Handle IP Lookup Results (None Check) Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/QUICK_START.md Shows how to safely handle the result of an IP address lookup, checking if `result` is not `None` before attempting to access its data. This prevents errors if the IP address is not found in the database. ```python if result: print(result['country']['iso_code']) else: print("IP not found") ``` -------------------------------- ### Core API Functions and Classes Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/INDEX.md This section details the primary entry point for opening a MaxMind DB database and the main interface for querying it, along with metadata access. ```APIDOC ## Core API ### `open_database(database, *, mode=MODE_AUTO, **kwargs)` #### Description Entry point for opening a MaxMind DB database file. #### Parameters - **database** (str or int) - Path to the database file or a file descriptor. - **mode** (int, optional) - The access mode for the database. Defaults to `MODE_AUTO`. - **kwargs** - Additional keyword arguments. #### Return Type `Reader` object ### `Reader` class #### Description Provides the query interface for the MaxMind DB database. #### Methods and Properties All methods and properties of the `Reader` class are documented. ### `Metadata` class #### Description Provides access to the database metadata information. #### Methods and Properties All methods and properties of the `Metadata` class are documented. ### Context Manager Protocol #### Description The `Reader` class supports the context manager protocol for proper resource management. ``` -------------------------------- ### Open Database with MODE_MMAP Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/QUICK_START.md Open a MaxMind DB file using the MODE_MMAP strategy. This mode does not require the C extension and is a good alternative if the extension is not available. ```python reader = maxminddb.open_database('db.mmdb', maxminddb.MODE_MMAP) ``` -------------------------------- ### Get IP Record and Prefix Length Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/QUICK_START.md Retrieves both the data record and the CIDR prefix length for a given IP address. This is useful when you need to know the specific network range the IP belongs to. ```python record, prefix_len = reader.get_with_prefix_len('1.2.3.4') ``` ```python if record: print(f"Network: /{prefix_len}") # e.g., /24 ``` -------------------------------- ### Handle TypeError for Invalid IP Address Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/errors.md Demonstrates how to catch a `TypeError` when an invalid type (e.g., an integer) is passed as an IP address to the `get()` method. This ensures robust handling of incorrect input types. ```python import maxminddb import ipaddress with maxminddb.open_database('db.mmdb') as reader: # TypeError: IP address must be string or ipaddress object try: result = reader.get(12345) # Integer, not IP address except TypeError as e: print(f"Type error: {e}") # Output: "argument 1 must be a string or ipaddress object" # Correct usage result = reader.get('1.2.3.4') result = reader.get(ipaddress.ip_address('1.2.3.4')) ``` -------------------------------- ### Decoder Constructor Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/api-reference/decoder-class.md Initializes the Decoder with a database buffer and optional pointer base and testing flags. ```python def __init__( self, database_buffer: FileBuffer | mmap.mmap | bytes, pointer_base: int = 0, pointer_test: bool = False, ) -> None ``` -------------------------------- ### Reader Method: get Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/api-reference/extension.md Returns the record for the given IP address, or None if not found. Raises `ValueError` for invalid IP addresses or IPv6 lookups in IPv4-only databases, and `TypeError` for invalid argument types. ```python def get(self, ip_address: str | IPv6Address | IPv4Address) -> Record | None ``` -------------------------------- ### Metadata Constructor Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/api-reference/extension.md The constructor for the Metadata object. It accepts keyword arguments, typically used to initialize the object with data from the database metadata. ```python def __init__(self, **kwargs: Any) -> None: pass ``` -------------------------------- ### Get Database Metadata Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/QUICK_START.md Accesses metadata associated with the MaxMind DB file, such as the database type, IP version support, and available languages. This information can be useful for understanding the database's contents and capabilities. ```python meta = reader.metadata() print(meta.database_type) # "GeoLite2-City" print(meta.ip_version) # 6 (supports IPv4+IPv6) print(meta.languages) # ["en", "es", "fr", ...] ``` -------------------------------- ### Lookup IP Address by IP Address Object Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/QUICK_START.md Demonstrates looking up an IP address using an `ipaddress` object (either IPv4 or IPv6). This requires importing the `ip_address` function from the `ipaddress` module. ```python from ipaddress import ip_address # By IP address object result = reader.get(ip_address('2001:db8::1')) ``` -------------------------------- ### Handle FileNotFoundError for Nonexistent Database Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/errors.md Shows how to catch a `FileNotFoundError` when attempting to open a database file that does not exist. This is crucial for preventing application crashes due to missing data files. ```python import maxminddb try: reader = maxminddb.open_database('nonexistent.mmdb') except FileNotFoundError as e: print(f"Database not found: {e}") ``` -------------------------------- ### Safe Initialization of MaxMind DB Reader Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/QUICK_START.md Safely open a MaxMind DB database file, handling potential FileNotFoundError and InvalidDatabaseError exceptions. Ensure the database path is correctly specified. ```python import maxminddb from pathlib import Path db_path = Path('GeoLite2-City.mmdb') try: reader = maxminddb.open_database(db_path) except FileNotFoundError: print("Database file not found") except maxminddb.InvalidDatabaseError: print("Database is corrupted") ``` -------------------------------- ### Structured Imports for Clarity Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/IMPORTS_GUIDE.md Organize your imports by bringing in specific functions like open_database, constants like MODE_MMAP, exceptions, and types like Record for better code readability and maintainability. ```python # Entry point from maxminddb import open_database # Modes from maxminddb import MODE_AUTO, MODE_MMAP # Exceptions from maxminddb import InvalidDatabaseError # Types for hints from maxminddb.types import Record # Usage with open_database('db.mmdb', MODE_MMAP) as reader: result: Record | None = reader.get('1.2.3.4') ``` -------------------------------- ### Instantiate Reader Class Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/api-reference/reader-class.md The Reader class can be instantiated with a database file path, file descriptor, or file-like object. The mode parameter controls how the database is opened. ```python import maxminddb # Example using a file path reader = maxminddb.Reader('GeoLite2-City.mmdb') # Example using a file-like object with open('GeoLite2-City.mmdb', 'rb') as f: reader = maxminddb.Reader(f) ``` -------------------------------- ### Use RecordDict for GeoIP Results Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/types.md Illustrates the typical usage of RecordDict for storing and accessing data from GeoIP lookups. Shows how to access nested values safely. ```python from maxminddb.types import RecordDict, Record # GeoIP database results are typically RecordDict geoip_result: RecordDict = { "country": { "iso_code": "US", "names": {"en": "United States"} }, "city": { "geoname_id": 5391959, "names": {"en": "San Francisco"} } } # Accessing nested values country_names: Record = geoip_result.get("country", {}).get("names", {}) ``` -------------------------------- ### Handle IPv6 Lookup in IPv4 Database Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/errors.md Demonstrates how to catch a ValueError when attempting to look up an IPv6 address in an IPv4-only database. Ensure you have a corresponding IPv4-only database file. ```python import maxminddb # IPv6 in IPv4 database try: with maxminddb.open_database('geoip2-ipv4-only.mmdb') as reader: result = reader.get('2001:db8::1') except ValueError as e: print(f"Invalid lookup: {e}") # Output: "Error looking up 2001:db8::1. You attempted to look up an IPv6 address in an IPv4-only database." ``` -------------------------------- ### Check IP Version Support Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/api-reference/metadata-class.md Determines the IP version supported by the database (4 for IPv4-only, 6 for dual-stack). Check this before attempting IPv6 lookups on IPv4-only databases to avoid errors. ```python meta.ip_version # 6 # Validate before IPv6 lookup if meta.ip_version == 4: print("This is an IPv4-only database") # Attempting IPv6 lookup would raise ValueError else: print("This database supports both IPv4 and IPv6") ``` -------------------------------- ### open_database() Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/QUICK_START.md Opens a MaxMind DB file, returning a Reader instance. Supports various input types for the database path and allows specifying an access mode. ```APIDOC ## open_database() Opens a MaxMind DB file, returning a Reader instance. ```python def open_database( database: str | PathLike | IO, mode: int = MODE_AUTO ) -> Reader ``` ### Parameters - **database**: Path to the MaxMind DB file (string, PathLike, or IO object). - **mode**: The access mode to use (defaults to `MODE_AUTO`). See Modes section for options. ### Examples ```python import maxminddb from pathlib import Path # String path reader = maxminddb.open_database('GeoLite2-City.mmdb') # PathLike object reader = maxminddb.open_database(Path('db.mmdb')) # Specific mode reader = maxminddb.open_database('db.mmdb', maxminddb.MODE_MMAP) ``` ``` -------------------------------- ### Safe GeoIP Database Initialization Wrapper Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/errors.md A class that safely initializes a GeoIP database reader, handling common initialization errors such as FileNotFoundError, InvalidDatabaseError, ValueError, and IOError. It provides a method to check readiness and perform lookups. ```python import maxminddb from typing import Optional class GeoIPLookup: """Safely initialized GeoIP database wrapper.""" def __init__(self, path: str, mode: int = maxminddb.MODE_AUTO): self.reader: Optional[maxminddb.Reader] = None self.error: Optional[str] = None try: self.reader = maxminddb.open_database(path, mode) except FileNotFoundError: self.error = f"Database not found: {path}" except maxminddb.InvalidDatabaseError as e: self.error = f"Invalid database: {e}" except ValueError as e: self.error = f"Configuration error: {e}" except IOError as e: self.error = f"I/O error: {e}" def get(self, ip: str) -> Optional[dict]: """Get location for IP, or None on error.""" if not self.reader: return None try: return self.reader.get(ip) except ValueError: # IPv6 in IPv4 database or invalid IP return None def close(self): """Close reader if open.""" if self.reader: self.reader.close() def is_ready(self) -> bool: """Check if lookup is ready.""" return self.reader is not None # Usage lookup = GeoIPLookup('GeoLite2-City.mmdb') if lookup.is_ready(): result = lookup.get('1.2.3.4') else: print(f"Not ready: {lookup.error}") ``` -------------------------------- ### Decoder Class Constructor Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/api-reference/decoder-class.md Initializes the Decoder with a database buffer and optional parameters for pointer resolution. ```APIDOC ## Decoder Class Signature ```python class Decoder: """Decoder for the data section of the MaxMind DB.""" ``` ## Constructor ```python def __init__( self, database_buffer: FileBuffer | mmap.mmap | bytes, pointer_base: int = 0, pointer_test: bool = False, ) -> None ``` ### Constructor Parameters | Parameter | Type | Required | Default | Description | |-----------|------|----------|---------|-------------| | `database_buffer` | `FileBuffer`, `mmap.mmap`, or `bytes` | Yes | — | The database buffer to decode from | | `pointer_base` | `int` | No | `0` | Base offset to use when resolving pointers in the data section | | `pointer_test` | `bool` | No | `False` | Internal testing flag; when True, pointer resolution returns the pointer value instead of decoding it | ``` -------------------------------- ### open_database Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/README.md Opens a MaxMind DB file and returns a Reader instance for performing lookups. ```APIDOC ## open_database ### Description Opens a MaxMind DB file and returns a Reader instance. ### Method `open_database` ### Parameters - **database** (AnyStr | int | PathLike | IO) - Description: Path to the MaxMind DB file or a file-like object. - **mode** (int) - Optional - Description: The mode to open the database in. Defaults to MODE_AUTO. ### Returns - **Reader** - An instance of the Reader class to interact with the database. ``` -------------------------------- ### Handle MODE_MMAP_EXT Unavailable Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/errors.md Illustrates catching a ValueError when MODE_MMAP_EXT is requested but the necessary C extension is not available. This mode requires the `maxminddb.extension` module. ```python import maxminddb # MODE_MMAP_EXT without extension try: reader = maxminddb.open_database('db.mmdb', maxminddb.MODE_MMAP_EXT) except ValueError as e: print(f"Extension unavailable: {e}") # Output: "MODE_MMAP_EXT requires the maxminddb.extension module to be available" ``` -------------------------------- ### High-Performance Server Import Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/IMPORTS_GUIDE.md Imports components for a high-performance server where the database reader is kept open for the server's lifetime. This pattern optimizes performance by avoiding repeated database opening. ```python from maxminddb import open_database, MODE_MMAP_EXT, MODE_AUTO from maxminddb.types import Record # Keep reader open for server lifetime reader = open_database('db.mmdb', MODE_MMAP_EXT if has_c_extension else MODE_AUTO) def handle_request(ip: str) -> Record | None: return reader.get(ip) # At shutdown reader.close() ``` -------------------------------- ### Context Manager Protocol Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/api-reference/reader-class.md The Reader class implements the context manager protocol, enabling its use with the `with` statement for automatic resource cleanup. ```APIDOC ## Context Manager Protocol ### Description The Reader class implements the context manager protocol, allowing it to be used with the `with` statement for automatic resource cleanup. ### Method Signatures ```python def __enter__(self) -> Self def __exit__(self, *_) -> None ``` ### Example ```python import maxminddb # Automatic cleanup with context manager with maxminddb.open_database('GeoLite2-City.mmdb') as reader: result = reader.get('1.2.3.4') # Database automatically closed here ``` ``` -------------------------------- ### Importing C Extension Reader and Metadata Types Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/IMPORTS_GUIDE.md If the C extension is available, you can import specific types like Reader and Metadata directly from maxminddb.extension for type hinting or direct use. ```python from maxminddb.extension import Reader as ExtensionReader from maxminddb.extension import Metadata as ExtensionMetadata ``` -------------------------------- ### Handle Invalid Open Mode Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/errors.md Shows how to catch a ValueError when an unsupported integer is provided as the open mode. Valid modes are constants like MODE_MMAP, MODE_FILE, etc. ```python import maxminddb # Invalid mode try: reader = maxminddb.open_database('db.mmdb', mode=999) except ValueError as e: print(f"Invalid mode: {e}") # Output: "Unsupported open mode: 999" ``` -------------------------------- ### Reader.get_with_prefix_len() Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/QUICK_START.md Retrieves data for an IP address along with its corresponding CIDR prefix length. ```APIDOC ## Reader.get_with_prefix_len() Returns both the record and the CIDR prefix length. ```python def get_with_prefix_len(ip_address: str) -> tuple[Record | None, int] ``` ### Parameters - **ip_address**: The IP address to look up (string). ### Returns A tuple containing the record (or None if not found) and the prefix length. ### Example ```python record, prefix_len = reader.get_with_prefix_len('1.2.3.4') if record: print(f"Network: /{prefix_len}") # e.g., /24 ``` ``` -------------------------------- ### Reader Method: get_with_prefix_len Source: https://github.com/maxmind/maxmind-db-reader-python/blob/main/_autodocs/api-reference/extension.md Returns a tuple containing the record for the given IP address and its corresponding prefix length, or (None, 0) if not found. ```python def get_with_prefix_len( self, ip_address: str | IPv6Address | IPv4Address, ) -> tuple[Record | None, int] ```