CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-ipinfo

Official Python library for IPInfo IP address geolocation and data lookups

Pending
Overview
Eval results
Files

data-utilities.mddocs/

Data Structures and Utilities

Response objects, caching system, exception handling, and utility functions for data formatting, validation, and configuration management in the IPInfo Python library.

Capabilities

Details Response Object

The primary response object that encapsulates IP address information with attribute-based access and data enrichment functionality.

class Details:
    def __init__(self, details):
        """
        Initialize Details object with IP information dictionary.
        
        Parameters:
        - details (dict): Dictionary containing IP address information
        """
        
    def __getattr__(self, attr):
        """
        Return attribute if it exists in details, else raise AttributeError.
        
        Parameters:
        - attr (str): Attribute name to access
        
        Returns:
        Any: Value of the requested attribute
        
        Raises:
        AttributeError: When attribute doesn't exist in details
        """
        
    @property
    def all(self):
        """
        Return all details as dictionary.
        
        Returns:
        dict: Complete details dictionary
        """

Exception Classes

Specialized exception classes for handling API errors, quota limits, and timeout conditions.

class RequestQuotaExceededError(Exception):
    """
    Error indicating that user's monthly request quota has been exceeded.
    
    Raised when API returns 429 status code.
    """

class TimeoutExceededError(Exception):
    """
    Error indicating that some timeout has been exceeded.
    
    Raised when operation exceeds specified timeout limits.
    """

class APIError(Exception):
    def __init__(self, error_code, error_json):
        """
        General API error with status code and response details.
        
        Parameters:
        - error_code (int): HTTP status code
        - error_json (dict): Error response JSON
        """
        
    def __str__(self):
        """
        Return formatted error string with code and JSON response.
        
        Returns:
        str: Formatted error message
        """

Cache System

Abstract cache interface and default LRU implementation for efficient IP data caching.

class CacheInterface:
    """Abstract interface for custom cache implementations."""
    
    def __contains__(self, key):
        """Check if key exists in cache."""
        
    def __setitem__(self, key, value):
        """Set cache value for key."""
        
    def __getitem__(self, key):
        """Get cache value for key."""
        
    def __delitem__(self, key):
        """Delete cache entry for key."""

class DefaultCache(CacheInterface):
    def __init__(self, **cache_options):
        """
        Default in-memory LRU cache with TTL support.
        
        Parameters:
        - **cache_options: Options passed to cachetools.TTLCache
          - maxsize (int): Maximum cache entries (default: 4096)
          - ttl (int): Time to live in seconds (default: 86400)
        """
        
    def __contains__(self, key):
        """Check if key exists in cache."""
        
    def __setitem__(self, key, value):
        """Set cache value for key."""
        
    def __getitem__(self, key):
        """Get cache value for key."""
        
    def __delitem__(self, key):
        """Delete cache entry for key."""

Utility Functions

Helper functions for HTTP headers, data formatting, file I/O, and cache key management.

def get_headers(access_token, custom_headers):
    """
    Build headers for request to IPinfo API.
    
    Parameters:
    - access_token (str, optional): API access token
    - custom_headers (dict, optional): Custom HTTP headers
    
    Returns:
    dict: Complete headers dictionary with user-agent, accept, and authorization
    """

def format_details(details, countries, eu_countries, countries_flags, countries_currencies, continents):
    """
    Format details dictionary with additional country and geographic data.
    
    Adds country_name, isEU, country_flag_url, country_flag, 
    country_currency, continent, latitude, and longitude fields.
    
    Parameters:
    - details (dict): Raw IP details to format
    - countries (dict): Country code to name mappings
    - eu_countries (list): List of EU country codes
    - countries_flags (dict): Country flag data
    - countries_currencies (dict): Country currency data
    - continents (dict): Continent mappings
    """

def read_coords(location):
    """
    Parse location string into latitude and longitude tuple.
    
    Parameters:
    - location (str): Location string in format "lat,lon"
    
    Returns:
    tuple: (latitude, longitude) as strings, or (None, None) if invalid
    """

def read_json_file(json_file):
    """
    Read and parse JSON file from package data directory.
    
    Parameters:
    - json_file (str): Filename relative to package directory
    
    Returns:
    dict: Parsed JSON data
    """

def return_or_fail(raise_on_fail, e, v):
    """
    Either raise exception or return value based on flag.
    
    Parameters:
    - raise_on_fail (bool): Whether to raise exception
    - e (Exception): Exception to raise
    - v (Any): Value to return if not raising
    
    Returns:
    Any: Returns v if raise_on_fail is False
    
    Raises:
    Exception: Raises e if raise_on_fail is True
    """

def cache_key(k):
    """
    Transform user input key into versioned cache key.
    
    Parameters:
    - k (str): User input key
    
    Returns:
    str: Versioned cache key
    """

Bogon Detection

Functions for identifying private and reserved IP address ranges.

def is_bogon(ip_address):
    """
    Check if IP address is a bogon (private/reserved address).
    
    Parameters:
    - ip_address (str): IP address to check
    
    Returns:
    bool: True if IP is in bogon networks, False otherwise
    """

# Predefined bogon networks
BOGON_NETWORKS = [
    # IPv4 bogon networks
    ipaddress.ip_network("0.0.0.0/8"),      # This network
    ipaddress.ip_network("10.0.0.0/8"),     # Private-use
    ipaddress.ip_network("127.0.0.0/8"),    # Loopback
    ipaddress.ip_network("169.254.0.0/16"), # Link-local
    ipaddress.ip_network("172.16.0.0/12"),  # Private-use
    ipaddress.ip_network("192.168.0.0/16"), # Private-use
    # ... additional bogon networks
]

Data Constants

Pre-loaded geographic and internationalization data for response enrichment.

# Geographic data mappings
continents = {
    "US": {"code": "NA", "name": "North America"},
    "GB": {"code": "EU", "name": "Europe"},
    # ... complete country to continent mappings
}

countries = {
    "US": "United States",
    "GB": "United Kingdom", 
    # ... complete country code to name mappings
}

countries_currencies = {
    "US": {"code": "USD", "symbol": "$"},
    "GB": {"code": "GBP", "symbol": "£"},
    # ... complete currency mappings
}

eu_countries = [
    "AT", "BE", "BG", "HR", "CY", "CZ", "DK", "EE", "FI", "FR",
    "DE", "GR", "HU", "IE", "IT", "LV", "LT", "LU", "MT", "NL",
    "PL", "PT", "RO", "SK", "SI", "ES", "SE"
]

countries_flags = {
    "US": {"emoji": "🇺🇸", "unicode": "U+1F1FA U+1F1F8"},
    "GB": {"emoji": "🇬🇧", "unicode": "U+1F1EC U+1F1E7"},
    # ... complete flag mappings
}

# API endpoints and configuration
API_URL = "https://ipinfo.io"
LITE_API_URL = "https://api.ipinfo.io/lite"
COUNTRY_FLAGS_URL = "https://cdn.ipinfo.io/static/images/countries-flags/"
BATCH_MAX_SIZE = 1000
CACHE_MAXSIZE = 4096
CACHE_TTL = 86400  # 24 hours
REQUEST_TIMEOUT_DEFAULT = 2
BATCH_REQ_TIMEOUT_DEFAULT = 5

Usage Examples

Custom Cache Implementation

import ipinfo
from ipinfo.cache.interface import CacheInterface
import redis

class RedisCache(CacheInterface):
    """Redis-based cache implementation"""
    
    def __init__(self, redis_client, ttl=86400):
        self.redis = redis_client
        self.ttl = ttl
    
    def __contains__(self, key):
        return self.redis.exists(key)
    
    def __setitem__(self, key, value):
        import json
        self.redis.setex(key, self.ttl, json.dumps(value))
    
    def __getitem__(self, key):
        import json
        value = self.redis.get(key)
        if value is None:
            raise KeyError(key)
        return json.loads(value)
    
    def __delitem__(self, key):
        self.redis.delete(key)

# Use custom cache
redis_client = redis.Redis()
custom_cache = RedisCache(redis_client)
handler = ipinfo.getHandler('token', cache=custom_cache)

Working with Details Object

import ipinfo

handler = ipinfo.getHandler('your_token')
details = handler.getDetails('8.8.8.8')

# Access individual attributes
print(details.city)          # Mountain View
print(details.country)       # US
print(details.country_name)  # United States
print(details.isEU)         # False
print(details.latitude)      # 37.3860
print(details.longitude)     # -122.0838

# Access all data as dictionary
all_data = details.all
print(all_data['hostname'])  # dns.google

# Handle missing attributes
try:
    print(details.nonexistent_field)
except AttributeError as e:
    print(f"Field not available: {e}")

Error Handling

import ipinfo
from ipinfo.exceptions import RequestQuotaExceededError, TimeoutExceededError
from ipinfo.error import APIError

handler = ipinfo.getHandler('invalid_token')

try:
    details = handler.getDetails('8.8.8.8')
except RequestQuotaExceededError:
    print("Quota exceeded - upgrade your plan")
except APIError as e:
    print(f"API Error {e.error_code}")
    print(f"Details: {e.error_json}")
except TimeoutExceededError:
    print("Request timed out")

Bogon Detection

from ipinfo.bogon import is_bogon

# Check if IP is private/reserved
print(is_bogon('192.168.1.1'))  # True (private)
print(is_bogon('8.8.8.8'))      # False (public)
print(is_bogon('127.0.0.1'))    # True (loopback)

Custom Data Files

import ipinfo

# Custom country names (e.g., for localization)
custom_countries = {
    "US": "États-Unis",
    "FR": "France",
    "DE": "Allemagne"
}

# Custom EU country list
custom_eu = ["FR", "DE", "IT", "ES"]  # Subset for example

handler = ipinfo.getHandler(
    'your_token',
    countries=custom_countries,
    eu_countries=custom_eu
)

details = handler.getDetails('8.8.8.8')
print(details.country_name)  # Uses custom mapping
print(details.isEU)         # Uses custom EU list

Types

# Details object structure
DetailsDict = {
    # Core API fields
    'ip': str,
    'hostname': str,
    'city': str,
    'region': str,
    'country': str,
    'loc': str,           # "latitude,longitude"
    'org': str,
    'postal': str,
    'timezone': str,
    
    # Enhanced fields (added by library)
    'country_name': str,
    'latitude': str,
    'longitude': str,
    'isEU': bool,
    'country_flag': dict,     # {"emoji": str, "unicode": str}
    'country_currency': dict, # {"code": str, "symbol": str}
    'continent': dict,        # {"code": str, "name": str}
    'country_flag_url': str,
    
    # Optional fields (may be present)
    'asn': dict,       # ASN information
    'company': dict,   # Company information
    'carrier': dict,   # Mobile carrier info
    'privacy': dict,   # Privacy/VPN detection
    'abuse': dict,     # Abuse contact info
    'domains': dict    # Associated domains
}

# Cache interface type
CacheInterface = {
    '__contains__': callable,
    '__getitem__': callable,
    '__setitem__': callable,
    '__delitem__': callable
}

# Geographic data types
CountryMapping = dict     # Country code -> name
ContinentMapping = dict   # Country code -> {"code": str, "name": str}
FlagMapping = dict        # Country code -> {"emoji": str, "unicode": str}
CurrencyMapping = dict    # Country code -> {"code": str, "symbol": str}

Install with Tessl CLI

npx tessl i tessl/pypi-ipinfo

docs

async-handlers.md

data-utilities.md

index.md

sync-handlers.md

tile.json