MaxMind DB Reader for Python

repository·main·Indexed 42 days ago

https://github.com/maxmind/maxmind-db-reader-python

A Python module (version 3.2.0) for reading MaxMind DB binary files containing data indexed by IPv4 or IPv6 subnets. It provides a high-performance C extension and a pure Python fallback, offering multiple access modes including memory mapping (MMAP_EXT, MMAP), standard file reading (FILE), and in-memory loading (MEMORY). The library includes the Reader class for performing IP lookups via get() and get_with_prefix_len(), and supports Python 3.13+ free-threading.

Tokens
3.5K
Snippets
16
Records
20
Agent score
53%

What's inside MaxMind DB Reader

  1. Thread safety and concurrency

    main

    Both the C extension and pure Python implementations are safe for concurrent reads.

    • Free-threading: The module supports Python 3.13+ free-threading. The C extension provides this on platforms with pthread support (Linux, macOS) and Windows. On other platforms, it uses GIL-based protection.
    • Warning: Calling .close() while reads are currently in progress in other threads may cause exceptions in those threads.
  2. Open a MaxMind DB and perform lookups

    main

    To use the module, use maxminddb.open_database() with the path to your .mmdb file. This returns a Reader object. You can use a with statement to ensure the reader is properly closed.

    Use .get(ip_address) to retrieve the record (usually a dictionary) for a specific IP. If no record is found, it returns None.

    Use .get_with_prefix_len(ip_address) to retrieve a tuple containing the record and the network prefix length.

    import maxminddb
    
    with maxminddb.open_database('GeoLite2-City.mmdb') as reader:
        # Get record
        record = reader.get('152.216.7.110')
        
        # Get record with prefix length
        record_with_prefix = reader.get_with_prefix_len('152.216.7.110')
  3. Install the maxminddb module

    main

    You can install the module via PyPI using pip. The installer will attempt to build a C extension for better performance; if the build fails, it will automatically fall back to a pure Python implementation.

    To install from PyPI:

    $ pip install maxminddb

    To install from a local source directory:

    $ python -m pip install .
  4. Manage Reader lifecycle with context managers

    main

    The Reader class supports the context manager protocol (with statement). Using a context manager ensures that the database file or memory map is properly closed when the block is exited, preventing resource leaks.

    from maxminddb import Reader
    
    # Recommended usage
    with Reader('GeoLite2-City.mmdb') as reader:
        data = reader.get('1.1.1.1')
    # Reader is automatically closed here
  5. Handle MaxMind DB exceptions

    main

    The following exceptions may be raised during operation:

    • InvalidDatabaseError: Raised if the database is corrupt, invalid, or if a record/metadata exceeds resource limits (65,536 decoded values, 512 levels of nesting, or 2 MiB of string/bytes data).
    • ValueError: Raised if you attempt to look up an invalid IP address or an IPv6 address in an IPv4 database.
  6. Iterate over all records in a MaxMind DB

    main

    The Reader class implements the __iter__ method, allowing you to loop through the entire database. Each iteration yields a tuple containing the network and the record.

    import maxminddb
    
    with maxminddb.open_database('GeoLite2-City.mmdb') as reader:
        for network, record in reader:
            print(network, record)
  7. Configure database reading modes with maxminddb.Mode

    main

    When calling open_database(path, mode), you can specify how the database is read using maxminddb.Mode.

    Available modes:

    • Mode.MMAP_EXT: Uses the C extension with memory map (fastest).
    • Mode.MMAP: Uses memory map via pure Python.
    • Mode.FILE: Reads database as a standard file (pure Python).
    • Mode.MEMORY: Loads the entire database into memory (pure Python).
    • Mode.FD: Loads database from a file descriptor (pure Python). Note: The caller is responsible for closing the file descriptor. You may close it immediately after creating the Reader.
    • Mode.AUTO: The default mode. It attempts Mode.MMAP_EXT, then Mode.MMAP, then Mode.FILE in that order.
    import maxminddb
    
    # Example using a specific mode
    with maxminddb.open_database('example.mmdb', mode=maxminddb.Mode.MEMORY) as reader:
        pass
  8. Initialize the Reader for MaxMind DB files

    main

    Use the Reader class to open a MaxMind DB file. You can provide a file path, a file descriptor, or an IO object. The mode parameter determines how the database is loaded into memory.

    Supported modes:

    • MODE_AUTO (Default): Tries MODE_MMAP first, then falls back to MODE_FILE.
    • MODE_MMAP: Reads from a memory map.
    • MODE_FILE: Reads the database as a standard file.
    • MODE_MEMORY: Loads the entire database into memory.
    • MODE_FD: Treats the database argument as a file descriptor (implies MODE_MEMORY).
    from maxminddb import Reader, MODE_MMAP
    
    # Using a file path with default mode (MODE_AUTO)
    with Reader('path/to/GeoLite2-City.mmdb') as reader:
        record = reader.get('128.101.101.101')
    
    # Using a specific mode
    reader = Reader('path/to/GeoLite2-City.mmdb', mode=MODE_MMAP)
  9. Access database metadata

    main

    The metadata() method returns a Metadata object containing information about the database file, such as its type, IP version, and build time.

    from maxminddb import Reader
    
    with Reader('GeoLite2-City.mmdb') as reader:
        meta = reader.metadata()
        print(f"Database Type: {meta.database_type}")
        print(f"IP Version: {meta.ip_version}")
        print(f"Node Count: {meta.node_count}")
  10. Look up IP address records with prefix length using get_with_prefix_len()

    main

    If you need to know the network prefix length associated with the found record, use get_with_prefix_len(). It returns a tuple containing the Record (or None) and the integer prefix_len.

    from maxminddb import Reader
    
    with Reader('GeoLite2-City.mmdb') as reader:
        record, prefix_len = reader.get_with_prefix_len('1.1.1.1')
        if record:
            print(f"Record: {record}, Prefix: {prefix_len}")
  11. Open a MaxMind DB using open_database()

    main

    Use open_database() to create a Reader instance for accessing MaxMind DB files. The function accepts a database path, a file descriptor, or a file-like object, and allows you to specify an access mode.

    If mode is set to MODE_AUTO (the default), the library will attempt to use the most efficient method available in this order: MODE_MMAP_EXT (C extension with memory map), MODE_MMAP (Pure Python memory map), and MODE_FILE (Pure Python standard file).

    from maxminddb import open_database
    
    # Open a database using the default auto mode
    reader = open_database('path/to/GeoLite2-City.mmdb')
    
    # Access data (assuming reader is a Reader instance)
    # data = reader.get('some_key')
  12. Look up IP address records with get()

    main

    The get() method returns the record associated with a specific IP address. The ip_address argument can be a string in standard notation or an ipaddress.IPv4Address/ipaddress.IPv6Address object. If no record is found, it returns None.

    from maxminddb import Reader
    
    with Reader('GeoLite2-City.mmdb') as reader:
        record = reader.get('1.1.1.1')
        if record:
            print(record)