Skip to main content

Python Client SDK Generated by Speakeasy.

Project description

๐ŸŒ GeoIP Python SDK

Enterprise-grade IP Geolocation API client for Python

A developer-friendly, type-safe Python SDK for the GeoIPAPI.com service, providing real-time IP geolocation data for personalization, analytics, and security applications.

๐Ÿ“‹ Table of Contents

โœจ Features

  • ๐ŸŽฏ Type-safe - Full TypeScript-style type annotations with Pydantic
  • โšก Async/Sync - Support for both synchronous and asynchronous operations
  • ๐Ÿ”„ Automatic Retries - Configurable retry strategies with exponential backoff
  • ๐Ÿ›ก๏ธ Error Handling - Comprehensive error handling with custom exceptions
  • ๐ŸŒ Multiple Formats - Support for JSON, JSONP, XML, and YAML response formats
  • ๐Ÿ”ง Customizable - Custom HTTP clients, headers, and configuration options
  • ๐Ÿ“ Well Documented - Extensive documentation and examples
  • ๐Ÿข Enterprise Ready - Built for production use with proper resource management

๐Ÿš€ Quick Start

from geoipapi import GeoIP

# Initialize the client
with GeoIP() as client:
    # Get current IP address
    response = client.geo_ip_endpoints.get_ip()
    print(f"Your IP: {response}")
    
    # Get detailed geolocation data
    geo_data = client.geo_ip_endpoints.get_ip_data()
    print(f"Location: {geo_data}")

๐Ÿ“ฆ Installation

The SDK supports multiple installation methods to fit your development workflow.

Using pip

pip install geoipapi

Using Poetry

poetry add geoipapi

Using uv (Recommended for scripts)

For quick scripts without setting up a full project:

uvx --from geoipapi python

Or create a standalone script:

#!/usr/bin/env -S uv run --script
# /// script
# requires-python = ">=3.9"
# dependencies = [
#     "geoipapi",
# ]
# ///

from geoipapi import GeoIP

# Your code here...

Save as script.py and run with uv run script.py.

Development Installation

For contributing or development:

git clone <repository-url>
cd geo-ip-python
pip install -e ".[dev]"

๐Ÿ’ก Usage Examples

Basic Synchronous Usage

from geoipapi import GeoIP

# Using context manager (recommended)
with GeoIP() as client:
    # Get your current IP address
    ip_response = client.geo_ip_endpoints.get_ip()
    print(f"Current IP: {ip_response}")
    
    # Get detailed geolocation information
    geo_data = client.geo_ip_endpoints.get_ip_data()
    print(f"Country: {geo_data.country}")
    print(f"City: {geo_data.city}")
    print(f"Coordinates: {geo_data.lat}, {geo_data.lon}")

Asynchronous Usage

import asyncio
from geoipapi import GeoIP

async def main():
    async with GeoIP() as client:
        # Async operations
        ip_response = await client.geo_ip_endpoints.get_ip_async()
        geo_data = await client.geo_ip_endpoints.get_ip_data_async()
        
        print(f"IP: {ip_response}")
        print(f"Location: {geo_data.city}, {geo_data.country}")

# Run the async function
asyncio.run(main())

Custom Configuration

from geoipapi import GeoIP
from geoipapi.utils import RetryConfig, BackoffStrategy

# Custom retry configuration
retry_config = RetryConfig(
    strategy="backoff",
    backoff=BackoffStrategy(
        initial_interval=1,
        max_interval=50,
        exponent=1.1,
        max_elapsed_time=100
    ),
    retry_connection_errors=False
)

# Initialize with custom settings
with GeoIP(
    server_url="https://api.geoipapi.com",
    retry_config=retry_config
) as client:
    response = client.geo_ip_endpoints.get_ip()
    print(response)

๐Ÿ—๏ธ Project Structure

geo-ip-python/
โ”œโ”€โ”€ src/
โ”‚   โ””โ”€โ”€ geoipapi/           # Main SDK package
โ”‚       โ”œโ”€โ”€ __init__.py     # Package initialization
โ”‚       โ”œโ”€โ”€ sdk.py          # Main SDK class
โ”‚       โ”œโ”€โ”€ httpclient.py   # HTTP client abstractions
โ”‚       โ”œโ”€โ”€ utils/          # Utility functions and classes
โ”‚       โ”œโ”€โ”€ models/         # Data models and schemas
โ”‚       โ””โ”€โ”€ endpoints/      # API endpoint implementations
โ”œโ”€โ”€ docs/                   # Documentation files
โ”œโ”€โ”€ tests/                  # Test suite
โ”œโ”€โ”€ samples/                # Usage examples
โ”œโ”€โ”€ .devcontainer/          # Development container config
โ”œโ”€โ”€ pyproject.toml          # Project configuration
โ”œโ”€โ”€ README.md               # This file
โ”œโ”€โ”€ USAGE.md                # Detailed usage examples
โ””โ”€โ”€ CONTRIBUTING.md         # Contribution guidelines

๐Ÿ”ง Configuration

Environment Variables

Set the following environment variables for debugging and configuration:

# Enable debug logging
export GEOIP_DEBUG=true

# Custom API endpoint (optional)
export GEOIP_API_URL=https://api.geoipapi.com

Client Configuration

from geoipapi import GeoIP
import logging

# Configure logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger("geoipapi")

# Initialize with custom configuration
client = GeoIP(
    server_url="https://api.geoipapi.com",  # Custom server URL
    debug_logger=logger,                     # Custom logger
    timeout=30,                             # Request timeout
)

๐Ÿ“š API Reference

Available Resources and Operations

GeoIP Endpoints

  • get_ip() - Get Current IP Address

    • Returns the client's current public IP address
    • Async version: get_ip_async()
  • get_ip_data(ip_address: str = None) - Get Geolocation Data

    • Returns detailed geolocation information for an IP address
    • If no IP is provided, uses the client's current IP
    • Async version: get_ip_data_async()

Response Models

Example Response:

{
  "ip": "143.244.47.99",
  "type": "IPv4",
  "country": {
    "is_eu_member": false,
    "currency_code": "USD",
    "continent": "NA",
    "name": "United States",
    "country_code": "US",
    "state": "New York",
    "city": "New York",
    "zip": "10123",
    "timezone": "America/New_York"
  },
  "location": {
    "latitude": 40.7127491575256,
    "longitude": -74.0069576127413
  },
  "asn": {
    "number": 212238,
    "name": "Datacamp Limited",
    "network": "143.244.47.0/24",
    "type": "HOSTING"
  }
}

๐Ÿ”„ Error Handling

The SDK provides comprehensive error handling with specific exception types:

from geoipapi import GeoIP, errors

with GeoIP() as client:
    try:
        response = client.geo_ip_endpoints.get_ip_data("invalid-ip")
        print(response)
        
    except errors.HTTPValidationError as e:
        print(f"Validation error: {e.message}")
        print(f"Status code: {e.status_code}")
        
    except errors.APIError as e:
        print(f"API error: {e.message}")
        print(f"Status code: {e.status_code}")
        print(f"Response body: {e.body}")
        
    except Exception as e:
        print(f"Unexpected error: {e}")

Common Error Types

Error Type Status Code Description
HTTPValidationError 422 Invalid request parameters
APIError 4XX, 5XX General API errors
ConnectionError N/A Network connectivity issues
TimeoutError N/A Request timeout

๐Ÿ” Retries

Configure automatic retries for failed requests:

from geoipapi import GeoIP
from geoipapi.utils import RetryConfig, BackoffStrategy

# Per-operation retry
with GeoIP() as client:
    retry_config = RetryConfig(
        strategy="backoff",
        backoff=BackoffStrategy(
            initial_interval=1,    # Start with 1 second
            max_interval=50,       # Max 50 seconds between retries
            exponent=1.1,         # Exponential backoff factor
            max_elapsed_time=100  # Give up after 100 seconds total
        ),
        retry_connection_errors=False
    )
    
    response = client.geo_ip_endpoints.get_ip(retry_config)

# Global retry configuration
client = GeoIP(retry_config=retry_config)

๐Ÿ› ๏ธ Custom HTTP Client

Basic Custom Headers

from geoipapi import GeoIP
import httpx

# Add custom headers to all requests
http_client = httpx.Client(headers={
    "x-custom-header": "my-value",
    "user-agent": "MyApp/1.0"
})

client = GeoIP(client=http_client)

Advanced Custom Client

from geoipapi import GeoIP
from geoipapi.httpclient import AsyncHttpClient
import httpx
import uuid

class CustomClient(AsyncHttpClient):
    def __init__(self, client: AsyncHttpClient):
        self.client = client

    async def send(self, request: httpx.Request, **kwargs) -> httpx.Response:
        # Add custom logic before sending
        request.headers["request-id"] = str(uuid.uuid4())
        
        # Log the request
        print(f"Sending request to {request.url}")
        
        response = await self.client.send(request, **kwargs)
        
        # Log the response
        print(f"Received response: {response.status_code}")
        
        return response

    def build_request(self, method: str, url, **kwargs) -> httpx.Request:
        return self.client.build_request(method, url, **kwargs)

# Use the custom client
custom_client = CustomClient(httpx.AsyncClient())
client = GeoIP(async_client=custom_client)

๐Ÿ’พ Resource Management

Always use context managers for proper resource cleanup:

from geoipapi import GeoIP

# Recommended: Using context manager
def sync_example():
    with GeoIP() as client:
        response = client.geo_ip_endpoints.get_ip()
        return response

# For async operations
async def async_example():
    async with GeoIP() as client:
        response = await client.geo_ip_endpoints.get_ip_async()
        return response

# Manual cleanup (not recommended)
client = GeoIP()
try:
    response = client.geo_ip_endpoints.get_ip()
finally:
    client.close()  # Manual cleanup

๐Ÿ› Debugging

Enable Debug Logging

import logging
import os
from geoipapi import GeoIP

# Method 1: Environment variable
os.environ['GEOIP_DEBUG'] = 'true'

# Method 2: Custom logger
logging.basicConfig(
    level=logging.DEBUG,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)

client = GeoIP(debug_logger=logging.getLogger("geoipapi"))

Debug Output Example

2024-01-15 10:30:45 - geoipapi - DEBUG - Making request to https://api.geoipapi.com/ip
2024-01-15 10:30:45 - geoipapi - DEBUG - Request headers: {'user-agent': 'geoipapi-python/1.0.0'}
2024-01-15 10:30:46 - geoipapi - DEBUG - Response status: 200
2024-01-15 10:30:46 - geoipapi - DEBUG - Response body: {"ip": "203.0.113.1", ...}

๐Ÿงช Testing

Running Tests

# Install development dependencies
pip install -e ".[dev]"

# Run all tests
pytest

# Run with coverage
pytest --cov=geoipapi

# Run specific test file
pytest tests/test_endpoints.py

# Run with verbose output
pytest -v

Test Structure

tests/
โ”œโ”€โ”€ test_client.py          # Client initialization tests
โ”œโ”€โ”€ test_endpoints.py       # API endpoint tests
โ”œโ”€โ”€ test_error_handling.py  # Error handling tests
โ”œโ”€โ”€ test_retries.py         # Retry logic tests
โ””โ”€โ”€ conftest.py            # Test configuration

Writing Tests

import pytest
from geoipapi import GeoIP

def test_get_ip():
    with GeoIP() as client:
        response = client.geo_ip_endpoints.get_ip()
        assert response is not None
        # Add more assertions based on expected response format

@pytest.mark.asyncio
async def test_get_ip_async():
    async with GeoIP() as client:
        response = await client.geo_ip_endpoints.get_ip_async()
        assert response is not None

๐Ÿค Contributing

We welcome contributions! This project follows a collaborative development model.

Development Setup

  1. Fork and Clone

    git clone https://github.com/yourusername/geo-ip-python.git
    cd geo-ip-python
    
  2. Create Development Environment

    # Using poetry (recommended)
    poetry install --with dev
    
    # Or using pip
    pip install -e ".[dev]"
    
  3. Run Tests

    pytest
    

Contribution Guidelines

  • Code Style: Follow PEP 8 and use type hints
  • Testing: Add tests for new features and bug fixes
  • Documentation: Update docs for any API changes
  • Commits: Use clear, descriptive commit messages
  • Pull Requests: Include description of changes and test results

Development Commands

# Format code
black src/ tests/

# Lint code
flake8 src/ tests/

# Type checking
mypy src/

# Run all checks
pre-commit run --all-files

For detailed contribution guidelines, see CONTRIBUTING.md.

๐Ÿ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

MIT License

Copyright (c) 2024 GeoIP Python SDK

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

โญ Star this repository if you find it useful! โญ

Report Issues โ€ข Discussions โ€ข API Documentation

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

geoipapi-0.0.1.tar.gz (32.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

geoipapi-0.0.1-py3-none-any.whl (44.7 kB view details)

Uploaded Python 3

File details

Details for the file geoipapi-0.0.1.tar.gz.

File metadata

  • Download URL: geoipapi-0.0.1.tar.gz
  • Upload date:
  • Size: 32.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.10.12

File hashes

Hashes for geoipapi-0.0.1.tar.gz
Algorithm Hash digest
SHA256 ef5e7bedb8e1dab2a6ddf529a931472af6a992b366ad4aecd916988630205884
MD5 838cd504c924dc796baa4f0a71a0e9c9
BLAKE2b-256 1f01d35913794b87272978395ba6e745a849c45d2cd44ad6505f4b17470f0d5a

See more details on using hashes here.

File details

Details for the file geoipapi-0.0.1-py3-none-any.whl.

File metadata

  • Download URL: geoipapi-0.0.1-py3-none-any.whl
  • Upload date:
  • Size: 44.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.10.12

File hashes

Hashes for geoipapi-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 ccc8a54a56f60d48b62733184f0feb207297819578edeafb9082d68ed876495c
MD5 574f7139bb2b23869ea226b4ab14e838
BLAKE2b-256 38b0c94ed5997c7589ab48bd40ddcd6be7306983b1c4dc417eb61da7953ed98e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page