Skip to content

oschwald/maxminddb-rust-python

Repository files navigation

maxminddb-rust

A high-performance Rust-based Python module for MaxMind DB files. Provides 100% API compatibility with the official maxminddb module with similar performance.

Performance

Benchmark results using 10 million random IP lookups per database (single-threaded):

Database Size Lookups/sec
GeoLite2-Country 9.4MB 527,297
GeoLite2-City 61MB 338,879
GeoIP2-City 117MB 332,827

Test Environment: Intel Core Ultra 7 265K (20 cores, up to 6.5GHz), Linux 6.17

These are single-threaded results; the reader is fully thread-safe and can be shared across multiple threads for parallel lookups.

Features

API Compatibility

This package provides 100% API compatibility with the official maxminddb Python module:

Supported:

  • Reader class with get(), get_with_prefix_len(), metadata(), and close() methods
  • open_database() function
  • ✅ Context manager support (with statement)
  • ✅ MODE_* constants (MODE_AUTO, MODE_MMAP, etc.)
  • InvalidDatabaseError exception
  • Metadata class with all attributes and computed properties
  • ✅ Support for string IP addresses and ipaddress.IPv4Address/IPv6Address objects
  • closed attribute
  • ✅ Iterator support (__iter__) for iterating over all database records

Extensions (not in original):

  • get_many() - Batch lookup method for processing multiple IPs efficiently

Not Yet Implemented:

  • ⏸️ MODE_FILE mode (currently only MODE_AUTO, MODE_MMAP, and MODE_MEMORY supported)
  • ⏸️ File descriptor support in constructor

Installation

From PyPI

pip install maxminddb-rust

From Source

maturin develop --release

Usage

This module provides the same API as maxminddb, just with a different import name:

import maxminddb_rust  # High-performance Rust implementation

# Open database
reader = maxminddb_rust.open_database("/var/lib/GeoIP/GeoIP2-City.mmdb")

# Lookup single IP
result = reader.get("8.8.8.8")
print(result)

# Lookup with prefix length
result, prefix_len = reader.get_with_prefix_len("8.8.8.8")
print(f"Result: {result}, Prefix: {prefix_len}")

# Use with ipaddress objects
import ipaddress
ip = ipaddress.IPv4Address("8.8.8.8")
result = reader.get(ip)

# Access metadata
metadata = reader.metadata()
print(f"Database type: {metadata.database_type}")
print(f"Node count: {metadata.node_count}")

# Context manager support
with maxminddb_rust.open_database("/var/lib/GeoIP/GeoIP2-City.mmdb") as reader:
    result = reader.get("1.1.1.1")
    print(result)

Batch Lookup (Extension)

The get_many() method is an extension not available in the original maxminddb module:

import maxminddb_rust

reader = maxminddb_rust.open_database("/var/lib/GeoIP/GeoIP2-City.mmdb")

# Lookup multiple IPs at once
ips = ["8.8.8.8", "1.1.1.1", "208.67.222.222"]
results = reader.get_many(ips)

for ip, result in zip(ips, results):
    print(f"{ip}: {result}")

Iterator Support

Iterate over all networks in the database:

import maxminddb_rust

reader = maxminddb_rust.open_database("/var/lib/GeoIP/GeoLite2-Country.mmdb")

# Iterate over all networks in the database
for network, data in reader:
    print(f"{network}: {data['country']['iso_code']}")

Database Modes

Choose between memory-mapped files (default, best performance) and in-memory mode:

import maxminddb_rust

# MODE_AUTO: Uses memory-mapped files (default, fastest)
reader = maxminddb_rust.open_database("/var/lib/GeoIP/GeoIP2-City.mmdb", mode=maxminddb_rust.MODE_AUTO)

# MODE_MMAP: Explicitly use memory-mapped files
reader = maxminddb_rust.open_database("/var/lib/GeoIP/GeoIP2-City.mmdb", mode=maxminddb_rust.MODE_MMAP)

# MODE_MEMORY: Load entire database into memory (useful for embedded systems or when file handle limits are a concern)
reader = maxminddb_rust.open_database("/var/lib/GeoIP/GeoIP2-City.mmdb", mode=maxminddb_rust.MODE_MEMORY)

Examples

The examples/ directory contains complete working examples demonstrating various use cases:

Run any example:

uv run python examples/basic_usage.py
uv run python examples/batch_processing.py

Documentation

  • API Documentation: All classes and methods include comprehensive docstrings. Use Python's built-in help():
    import maxminddb_rust
    help(maxminddb_rust.open_database)
    help(maxminddb_rust.Reader.get)
  • Type Hints: Full type stub file (maxminddb_rust.pyi) included for IDE autocomplete and type checking
  • Changelog: See CHANGELOG.md for version history and release notes
  • Migration Guide: See MIGRATION.md for migrating from the official maxminddb package

Benchmarking

Run the included benchmarks (after building from source):

# Single lookup benchmark
uv run python benchmark.py --file /var/lib/GeoIP/GeoIP2-City.mmdb --count 250000

# Comprehensive benchmark across multiple databases
uv run python benchmark_comprehensive.py --count 250000

# Batch lookup benchmark
uv run python benchmark_batch.py --file /var/lib/GeoIP/GeoIP2-City.mmdb --batch-size 100

Testing

This project includes comprehensive tests, including upstream compatibility tests from MaxMind-DB-Reader-python.

# Initialize test data submodule (first time only)
git submodule update --init --recursive

# Run all tests
uv run pytest

# Run with verbose output
uv run pytest -v

For contributor information including development setup, code quality tools, and test syncing, see CONTRIBUTING.md.

For upstream test compatibility and syncing instructions, see tests/maxmind/README.md.

License

ISC License - see LICENSE file for details.

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for development setup, code quality guidelines, and pull request procedures.

About

Python wrapper using Rust maxminddb crate

Resources

License

Contributing

Stars

Watchers

Forks

Packages

No packages published

Contributors 3

  •  
  •  
  •