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

web-service.mddocs/

Web Service Client

Synchronous and asynchronous clients for accessing MaxMind's GeoIP2 and GeoLite2 web services. The clients provide access to Country, City Plus, and Insights endpoints with comprehensive authentication, error handling, and proxy support.

from collections.abc import Sequence
from typing import Optional

from geoip2.models import City, Country, Insights
from geoip2.types import IPAddress

Capabilities

Synchronous Client

The synchronous Client class provides blocking HTTP requests to MaxMind's web services using the requests library.

class Client:
    def __init__(self, account_id: int, license_key: str, host: str = "geoip.maxmind.com", 
                 locales: Optional[Sequence[str]] = None, timeout: float = 60, 
                 proxy: Optional[str] = None):
        """
        Create a synchronous GeoIP2 client.
        
        Parameters:
        - account_id: MaxMind account ID
        - license_key: MaxMind license key
        - host: Hostname for requests (default: "geoip.maxmind.com")
               Use "geolite.info" for GeoLite2 web service
               Use "sandbox.maxmind.com" for Sandbox GeoIP2 web service
        - locales: List of locale codes for name properties (default: ['en'])
                  Valid codes: 'de', 'en', 'es', 'fr', 'ja', 'pt-BR', 'ru', 'zh-CN'
        - timeout: Request timeout in seconds (default: 60)
        - proxy: HTTP proxy URL with optional basic auth
        """
    
    def city(self, ip_address: IPAddress = "me") -> City:
        """
        Call City Plus endpoint with the specified IP.
        
        Parameters:
        - ip_address: IPv4 or IPv6 address as string, or "me" for caller's IP
        
        Returns:
        City model object containing geographic data
        
        Raises:
        - AddressNotFoundError: IP address not found in database
        - AuthenticationError: Invalid credentials
        - OutOfQueriesError: Account out of queries
        - HTTPError: HTTP transport error
        """
    
    def country(self, ip_address: IPAddress = "me") -> Country:
        """
        Call GeoIP2 Country endpoint with the specified IP.
        
        Parameters:
        - ip_address: IPv4 or IPv6 address as string, or "me" for caller's IP
        
        Returns:
        Country model object containing country-level geographic data
        
        Raises:
        - AddressNotFoundError: IP address not found in database
        - AuthenticationError: Invalid credentials
        - OutOfQueriesError: Account out of queries
        - HTTPError: HTTP transport error
        """
    
    def insights(self, ip_address: IPAddress = "me") -> Insights:
        """
        Call Insights endpoint with the specified IP.
        
        Note: Insights is only supported by GeoIP2 web service, not GeoLite2.
        
        Parameters:
        - ip_address: IPv4 or IPv6 address as string, or "me" for caller's IP
        
        Returns:
        Insights model object containing comprehensive data including user behavior analytics
        
        Raises:
        - AddressNotFoundError: IP address not found in database
        - AuthenticationError: Invalid credentials
        - OutOfQueriesError: Account out of queries
        - PermissionRequiredError: Account lacks Insights permission
        - HTTPError: HTTP transport error
        """
    
    def close(self):
        """Close underlying HTTP session and connections."""
    
    def __enter__(self) -> "Client": ...
    def __exit__(self, exc_type, exc_value, traceback): ...

Asynchronous Client

The AsyncClient class provides non-blocking HTTP requests using aiohttp for integration with asyncio applications.

class AsyncClient:
    def __init__(self, account_id: int, license_key: str, host: str = "geoip.maxmind.com", 
                 locales: Optional[Sequence[str]] = None, timeout: float = 60, 
                 proxy: Optional[str] = None):
        """
        Create an asynchronous GeoIP2 client.
        
        Parameters are identical to synchronous Client.
        Note: Client objects should not be shared across different event loops.
        """
    
    async def city(self, ip_address: IPAddress = "me") -> City:
        """
        Async version of city endpoint call.
        
        Parameters and returns are identical to synchronous version.
        """
    
    async def country(self, ip_address: IPAddress = "me") -> Country:
        """
        Async version of country endpoint call.
        
        Parameters and returns are identical to synchronous version.
        """
    
    async def insights(self, ip_address: IPAddress = "me") -> Insights:
        """
        Async version of insights endpoint call.
        
        Parameters and returns are identical to synchronous version.
        """
    
    async def close(self):
        """Close underlying aiohttp session and connections."""
    
    async def __aenter__(self) -> "AsyncClient": ...
    async def __aexit__(self, exc_type, exc_value, traceback): ...

Usage Examples

Basic Synchronous Usage

import geoip2.webservice

# Create client with credentials
with geoip2.webservice.Client(42, 'your_license_key') as client:
    # Query an IP address
    response = client.city('203.0.113.0')
    
    # Access geographic data
    print(f"Country: {response.country.name}")
    print(f"City: {response.city.name}")
    print(f"Coordinates: {response.location.latitude}, {response.location.longitude}")

Basic Asynchronous Usage

import asyncio
import geoip2.webservice

async def lookup_ip(ip_address):
    async with geoip2.webservice.AsyncClient(42, 'your_license_key') as client:
        response = await client.city(ip_address)
        return response.country.name

# Run async function
country = asyncio.run(lookup_ip('203.0.113.0'))

Using Different Services

with geoip2.webservice.Client(42, 'license_key') as client:
    # Country-level data only (faster, less detailed)
    country_response = client.country('203.0.113.0')
    
    # City-level data (includes country data plus city, subdivision, postal)
    city_response = client.city('203.0.113.0')
    
    # Insights data (includes city data plus user behavior analytics)
    insights_response = client.insights('203.0.113.0')

Using GeoLite2 Web Service

# Use GeoLite2 instead of GeoIP2
with geoip2.webservice.Client(42, 'license_key', host='geolite.info') as client:
    response = client.city('203.0.113.0')
    # Note: Insights is not available on GeoLite2

Custom Configuration

# Custom locales, timeout, and proxy
with geoip2.webservice.Client(
    account_id=42,
    license_key='license_key',
    locales=['es', 'en'],  # Spanish first, English fallback
    timeout=30,            # 30 second timeout
    proxy='http://proxy.example.com:8080'
) as client:
    response = client.city('203.0.113.0')
    print(response.country.name)  # Name in Spanish if available

Error Handling

import geoip2.webservice
from geoip2.errors import AddressNotFoundError, AuthenticationError, OutOfQueriesError

try:
    with geoip2.webservice.Client(42, 'license_key') as client:
        response = client.city('127.0.0.1')  # Private IP
except AddressNotFoundError:
    print("IP address not found in database")
except AuthenticationError:
    print("Invalid account ID or license key")
except OutOfQueriesError:
    print("Account is out of queries")

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