CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-geoip2

MaxMind GeoIP2 API for IP geolocation using web services and databases

Pending
Overview
Eval results
Files

database-reader.mddocs/

Database Reader

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.

import os
from collections.abc import Sequence
from typing import IO, AnyStr, Optional, Union

import maxminddb

from geoip2.models import (
    ASN, ISP, AnonymousIP, AnonymousPlus, City, ConnectionType, 
    Country, Domain, Enterprise
)
from geoip2.types import IPAddress

Capabilities

Database Reader

The Reader class provides high-performance local database lookups without requiring network connectivity.

class Reader:
    def __init__(self, fileish: Union[AnyStr, int, os.PathLike, IO], 
                 locales: Optional[Sequence[str]] = None, mode: int = MODE_AUTO):
        """
        Create a GeoIP2 database reader.
        
        Parameters:
        - fileish: Path to MMDB file, file descriptor, or file-like object
        - locales: List of locale codes for name properties (default: ['en'])
                  Valid codes: 'de', 'en', 'es', 'fr', 'ja', 'pt-BR', 'ru', 'zh-CN'
        - mode: Database access mode (default: MODE_AUTO)
        """
    
    def city(self, ip_address: IPAddress) -> City:
        """
        Get City object for the IP address from City or Enterprise database.
        
        Parameters:
        - ip_address: IPv4 or IPv6 address as string
        
        Returns:
        City model object with geographic data including city, country, subdivisions
        
        Raises:
        - AddressNotFoundError: IP address not found in database
        - TypeError: Database type doesn't support city lookups
        """
    
    def country(self, ip_address: IPAddress) -> Country:
        """
        Get Country object for the IP address from Country, City, or Enterprise database.
        
        Parameters:
        - ip_address: IPv4 or IPv6 address as string
        
        Returns:
        Country model object with country-level geographic data
        
        Raises:
        - AddressNotFoundError: IP address not found in database
        - TypeError: Database type doesn't support country lookups
        """
    
    def asn(self, ip_address: IPAddress) -> ASN:
        """
        Get ASN object for the IP address from ASN database.
        
        Parameters:
        - ip_address: IPv4 or IPv6 address as string
        
        Returns:
        ASN model object with autonomous system information
        
        Raises:
        - AddressNotFoundError: IP address not found in database
        - TypeError: Database type doesn't support ASN lookups
        """
    
    def isp(self, ip_address: IPAddress) -> ISP:
        """
        Get ISP object for the IP address from ISP database.
        
        Parameters:
        - ip_address: IPv4 or IPv6 address as string
        
        Returns:
        ISP model object with ISP and organization information
        
        Raises:
        - AddressNotFoundError: IP address not found in database
        - TypeError: Database type doesn't support ISP lookups
        """
    
    def anonymous_ip(self, ip_address: IPAddress) -> AnonymousIP:
        """
        Get AnonymousIP object for the IP address from Anonymous IP database.
        
        Parameters:
        - ip_address: IPv4 or IPv6 address as string
        
        Returns:
        AnonymousIP model object with anonymity indicators
        
        Raises:
        - AddressNotFoundError: IP address not found in database
        - TypeError: Database type doesn't support anonymous IP lookups
        """
    
    def anonymous_plus(self, ip_address: IPAddress) -> AnonymousPlus:
        """
        Get AnonymousPlus object for the IP address from Anonymous Plus database.
        
        Parameters:
        - ip_address: IPv4 or IPv6 address as string
        
        Returns:
        AnonymousPlus model object with enhanced anonymity information
        
        Raises:
        - AddressNotFoundError: IP address not found in database
        - TypeError: Database type doesn't support anonymous plus lookups
        """
    
    def connection_type(self, ip_address: IPAddress) -> ConnectionType:
        """
        Get ConnectionType object for the IP address from Connection-Type database.
        
        Parameters:
        - ip_address: IPv4 or IPv6 address as string
        
        Returns:
        ConnectionType model object with connection type information
        
        Raises:
        - AddressNotFoundError: IP address not found in database
        - TypeError: Database type doesn't support connection type lookups
        """
    
    def domain(self, ip_address: IPAddress) -> Domain:
        """
        Get Domain object for the IP address from Domain database.
        
        Parameters:
        - ip_address: IPv4 or IPv6 address as string
        
        Returns:
        Domain model object with domain information
        
        Raises:
        - AddressNotFoundError: IP address not found in database
        - TypeError: Database type doesn't support domain lookups
        """
    
    def enterprise(self, ip_address: IPAddress) -> Enterprise:
        """
        Get Enterprise object for the IP address from Enterprise database.
        
        Parameters:
        - ip_address: IPv4 or IPv6 address as string
        
        Returns:
        Enterprise model object with comprehensive geographic and network data
        
        Raises:
        - AddressNotFoundError: IP address not found in database
        - TypeError: Database type doesn't support enterprise lookups
        """
    
    def metadata(self) -> maxminddb.reader.Metadata:
        """
        Get metadata for the open database.
        
        Returns:
        Metadata object containing database information including build time,
        database type, IP version, record size, and node count
        """
    
    def close(self):
        """Close the GeoIP2 database and free resources."""
    
    def __enter__(self) -> "Reader": ...
    def __exit__(self, exc_type, exc_value, traceback): ...

Database Access Modes

Constants for controlling how the database is accessed, providing trade-offs between performance and memory usage.

from geoip2.database import (
    MODE_AUTO, MODE_FD, MODE_FILE, MODE_MEMORY, MODE_MMAP, MODE_MMAP_EXT
)

MODE_AUTO: int      # Try MODE_MMAP_EXT, MODE_MMAP, MODE_FILE in order (default)
MODE_FD: int        # fileish parameter is file descriptor, use MODE_MEMORY
MODE_FILE: int      # Read database as standard file (pure Python)
MODE_MEMORY: int    # Load entire database into memory (pure Python)
MODE_MMAP: int      # Memory map database file (pure Python)
MODE_MMAP_EXT: int  # Memory map with C extension (fastest performance)

Usage Examples

Basic Database Usage

import geoip2.database

# City database lookup
with geoip2.database.Reader('/path/to/GeoLite2-City.mmdb') as reader:
    response = reader.city('203.0.113.0')
    
    print(f"Country: {response.country.name}")
    print(f"City: {response.city.name}")
    print(f"Coordinates: {response.location.latitude}, {response.location.longitude}")
    print(f"Postal: {response.postal.code}")
    print(f"Subdivision: {response.subdivisions.most_specific.name}")

ASN Database Usage

with geoip2.database.Reader('/path/to/GeoLite2-ASN.mmdb') as reader:
    response = reader.asn('203.0.113.0')
    
    print(f"ASN: {response.autonomous_system_number}")
    print(f"Organization: {response.autonomous_system_organization}")
    print(f"Network: {response.network}")

Anonymous IP Database Usage

with geoip2.database.Reader('/path/to/GeoIP2-Anonymous-IP.mmdb') as reader:
    response = reader.anonymous_ip('203.0.113.0')
    
    print(f"Is Anonymous: {response.is_anonymous}")
    print(f"Is VPN: {response.is_anonymous_vpn}")
    print(f"Is Tor: {response.is_tor_exit_node}")
    print(f"Is Hosting Provider: {response.is_hosting_provider}")

Anonymous Plus Database Usage

with geoip2.database.Reader('/path/to/GeoIP-Anonymous-Plus.mmdb') as reader:
    response = reader.anonymous_plus('203.0.113.0')
    
    print(f"Anonymizer Confidence: {response.anonymizer_confidence}")
    print(f"Is Anonymous: {response.is_anonymous}")
    print(f"Is VPN: {response.is_anonymous_vpn}")
    print(f"Is Tor: {response.is_tor_exit_node}")
    print(f"Network Last Seen: {response.network_last_seen}")
    print(f"Provider Name: {response.provider_name}")

Connection Type Database Usage

with geoip2.database.Reader('/path/to/GeoIP2-Connection-Type.mmdb') as reader:
    response = reader.connection_type('203.0.113.0')
    
    print(f"Connection Type: {response.connection_type}")  # 'Corporate', 'Cable/DSL', etc.

ISP Database Usage

with geoip2.database.Reader('/path/to/GeoIP2-ISP.mmdb') as reader:
    response = reader.isp('203.0.113.0')
    
    print(f"ISP: {response.isp}")
    print(f"Organization: {response.organization}")
    print(f"ASN: {response.autonomous_system_number}")
    print(f"Mobile Country Code: {response.mobile_country_code}")

Domain Database Usage

with geoip2.database.Reader('/path/to/GeoIP2-Domain.mmdb') as reader:
    response = reader.domain('203.0.113.0')
    
    print(f"Domain: {response.domain}")

Enterprise Database Usage

with geoip2.database.Reader('/path/to/GeoIP2-Enterprise.mmdb') as reader:
    response = reader.enterprise('203.0.113.0')
    
    # Enterprise includes all city data plus confidence scores
    print(f"Country: {response.country.name} (confidence: {response.country.confidence})")
    print(f"City: {response.city.name} (confidence: {response.city.confidence})")
    print(f"Subdivision: {response.subdivisions.most_specific.name} (confidence: {response.subdivisions.most_specific.confidence})")

Custom Locales and Access Mode

# Use German with English fallback, memory-mapped access
with geoip2.database.Reader(
    '/path/to/GeoLite2-City.mmdb',
    locales=['de', 'en'],
    mode=geoip2.database.MODE_MMAP
) as reader:
    response = reader.city('203.0.113.0')
    print(response.country.name)  # German name if available

Database Metadata

with geoip2.database.Reader('/path/to/GeoLite2-City.mmdb') as reader:
    metadata = reader.metadata()
    
    print(f"Database Type: {metadata.database_type}")
    print(f"Build Date: {metadata.build_epoch}")
    print(f"IP Version: {metadata.ip_version}")
    print(f"Record Size: {metadata.record_size}")

Efficient Subnet Enumeration

import geoip2.database
import geoip2.errors
import ipaddress

# Efficiently enumerate entire subnets using AddressNotFoundError.network
with geoip2.database.Reader('/path/to/GeoLite2-ASN.mmdb') as reader:
    network = ipaddress.ip_network("192.128.0.0/15")
    
    ip_address = network[0]
    while ip_address in network:
        try:
            response = reader.asn(ip_address)
            response_network = response.network
            print(f"{response_network}: ASN {response.autonomous_system_number}")
        except geoip2.errors.AddressNotFoundError as e:
            response_network = e.network
            print(f"{response_network}: No data")
        
        # Move to next subnet
        ip_address = response_network[-1] + 1

Error Handling

import geoip2.database
from geoip2.errors import AddressNotFoundError

try:
    with geoip2.database.Reader('/path/to/GeoLite2-City.mmdb') as reader:
        response = reader.city('127.0.0.1')  # Private IP
except AddressNotFoundError as e:
    print(f"Address {e.ip_address} not found")
    print(f"Largest network with no data: {e.network}")
except FileNotFoundError:
    print("Database file not found")
except PermissionError:
    print("Permission denied accessing database file")

Types

IPAddress = Union[str, IPv6Address, IPv4Address]

Install with Tessl CLI

npx tessl i tessl/pypi-geoip2

docs

database-reader.md

errors.md

index.md

models.md

web-service.md

tile.json