IPGeolocation Python SDK

Overview

Typed Python SDK for the IPGeolocation.io IP Location API.

  • Single lookup ( /v3/ipgeo ) and bulk lookup ( /v3/ipgeo-bulk )
  • Sync client built on requests and async client built on httpx
  • Typed response models plus raw JSON/XML methods
  • Python 3.8+

Install

pip install ipgeolocationio

PyPI package: ipgeolocationio Package page: https://pypi.org/project/ipgeolocationio/ Import: ipgeolocation


Quick Start

from ipgeolocation import (
    IpGeolocationClient,
    IpGeolocationClientConfig,
    LookupIpGeolocationRequest,
)

config = IpGeolocationClientConfig(api_key="YOUR_API_KEY")

with IpGeolocationClient(config) as client:
    response = client.lookup_ip_geolocation(
        LookupIpGeolocationRequest(ip="8.8.8.8")
    )

    print(response.data.ip)

    if response.data.location is not None:
        print(response.data.location.country_name)
        print(response.data.location.city)

    if response.data.time_zone is not None:
        print(response.data.time_zone.name)

1. Async

import asyncio

from ipgeolocation import (
    AsyncIpGeolocationClient,
    IpGeolocationClientConfig,
    LookupIpGeolocationRequest,
)


async def main() -> None:
    config = IpGeolocationClientConfig(api_key="YOUR_API_KEY")

    async with AsyncIpGeolocationClient(config) as client:
        response = await client.lookup_ip_geolocation(
            LookupIpGeolocationRequest(ip="8.8.8.8")
        )
        print(response.data.ip)

        if response.data.location is not None:
            print(response.data.location.country_name)


asyncio.run(main())

The async client exposes the same methods as coroutines. Use async with for cleanup, or call await client.aclose() manually.


Authentication

API key: Works on all plans for single lookup and bulk lookup.

config = IpGeolocationClientConfig(api_key="YOUR_API_KEY")

Request-origin auth: Paid plans only, and only for single lookup. If your origin is allowlisted in the IPGeolocation dashboard, the SDK sends it in the Origin header.

config = IpGeolocationClientConfig(request_origin="https://app.example.com")

request_origin must be an absolute http or https URL with no path, query string, or fragment. Bulk lookups always require api_key , even if request_origin is set. You can set both on the same config. Single lookups require at least one of them.


1. Client Config

FieldUse
api_key API key auth for single lookup and bulk lookup
request_origin Paid request-origin auth for single lookup
base_url Override the API base URL
connect_timeout Time to wait for the connection in seconds
read_timeout Time to wait for the response body in seconds

Notes

  • Typed methods require JSON. For XML output, use the _raw methods with output=ResponseFormat.XML .
  • Optional modules need include . Fields like security , abuse , user_agent , hostname , geo_accuracy , and dma_code only appear in the response when you pass the matching include value. Without it, those fields will be None .
  • fields and excludes only filter the response. They do not enable optional modules or unlock paid data.
  • Domain lookup is paid only. Passing a domain as ip="google.com" works on paid plans. Free plans get a 401.
  • The SDK does not retry. Timeouts, server errors, and rate limits raise exceptions directly. Implement your own retry logic if you need it.
  • Do not reuse a closed client. After close() , aclose() , or leaving a with or async with block, further requests raise ValidationException .

Plan Behavior

Responses vary by plan.


1. Capabilities

CapabilityFreePaid
Single IPv4/IPv6 lookupTickTick
Domain lookupCrossTick
Bulk lookup ( /v3/ipgeo-bulk )CrossTick
Non-English lang CrossTick
Request-origin authCrossTick
Optional modules via include CrossTick
include=["*"] Base response onlyAll plan-available modules

2. Default Response Sections

Default single-lookup response:

SectionFreePaid
location TickTick
country_metadata TickTick
currency TickTick
asn (basic: as_number , organization , country )TickTick
asn (full: adds type , domain , date_allocated , rir )CrossTick
time_zone TickTick
network CrossTick
company CrossTick

Examples

The examples below assume you already have a configured client in scope. See Quick Start for setup.


1. Caller IP

Omit the ip parameter to look up the IP of the machine making the request:

response = client.lookup_ip_geolocation(LookupIpGeolocationRequest())
print(response.data.ip)  # your public IP

2. Domain Lookup (Paid)

When you look up a domain, the response includes the resolved IP and the original domain name:

response = client.lookup_ip_geolocation(
    LookupIpGeolocationRequest(ip="google.com")
)
print(response.data.ip)       # resolved IP address
print(response.data.domain)   # "google.com"

3. Security and Abuse

response = client.lookup_ip_geolocation(
    LookupIpGeolocationRequest(
        ip="9.9.9.9",
        include=["security", "abuse"],
    )
)

if response.data.security is not None:
    print(response.data.security.threat_score)

if response.data.abuse is not None and response.data.abuse.emails:
    print(response.data.abuse.emails[0])

4. User-Agent Parsing

To parse a visitor's user-agent string, pass include=["user_agent"] and send the visitor string in the request User-Agent header:

visitor_ua = (
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) "
    "AppleWebKit/601.3.9 (KHTML, like Gecko) Version/9.0.2 Safari/601.3.9"
)

response = client.lookup_ip_geolocation(
    LookupIpGeolocationRequest(
        ip="115.240.90.163",
        include=["user_agent"],
        headers={"User-Agent": visitor_ua},
    )
)

if response.data.user_agent is not None:
    print(response.data.user_agent.name)
    print(response.data.user_agent.operating_system)

5. Filtered Response

Use fields to keep specific fields, or excludes to remove them:

response = client.lookup_ip_geolocation(
    LookupIpGeolocationRequest(
        ip="8.8.8.8",
        include=["security"],
        fields=["location.country_name", "security.threat_score", "security.is_vpn"],
        excludes=["currency"],
    )
)

if response.data.location is not None:
    print(response.data.location.country_name)

if response.data.security is not None:
    print(response.data.security.threat_score)
    print(response.data.security.is_vpn)

6. Raw XML

Typed methods only support JSON. For XML, use a raw method:

from ipgeolocation import ResponseFormat

response = client.lookup_ip_geolocation_raw(
    LookupIpGeolocationRequest(ip="8.8.8.8", output=ResponseFormat.XML)
)
print(response.data)  # raw XML string

7. Bulk Lookup (Paid)

Bulk lookup uses POST and accepts up to 50,000 IPs or domains. Each item in the response is either BulkLookupSuccess or BulkLookupError :

from ipgeolocation import (
    BulkLookupError,
    BulkLookupIpGeolocationRequest,
    BulkLookupSuccess,
)

response = client.bulk_lookup_ip_geolocation(
    BulkLookupIpGeolocationRequest(
        ips=["8.8.8.8", "invalid-ip", "1.1.1.1"],
        include=["security"],
    )
)

for result in response.data:
    if isinstance(result, BulkLookupSuccess):
        print(result.data.ip, result.data.security)  # 8.8.8.8 Security(...)
    elif isinstance(result, BulkLookupError):
        print(result.error.message)  # 'invalid-ip' is not a valid IP address.

Request Options


1. Single Lookup

FieldTypeNotes
ip str or None IPv4, IPv6, or domain (domain is paid only). Omit for caller IP lookup.
lang Language , str , or None Response language. Non-English requires a paid plan.
include sequence of stringsOptional modules to enable. See include values.
fields sequence of stringsResponse field filter. Does not unlock data.
excludes sequence of stringsResponse field filter. Does not unlock data.
output ResponseFormat or str "json" (default) or "xml" . Typed methods require JSON.
user_agent str or None Overrides the outbound User-Agent header. Takes precedence over headers["User-Agent"] .
headers mapping of stringsCustom request headers. Accept is always SDK-managed. Sequence values are sent as one comma-joined header line.

2. Bulk Lookup

Bulk lookup accepts the same fields as single lookup, plus:

FieldTypeNotes
ips sequence of stringsRequired. Up to 50,000 IPs or domains.

Differences from single lookup: Content-Type: application/json is always set by the SDK. Bulk lookup always requires api_key in the config, even if request_origin is also set.


3. include Values

ValueWhat it adds
security security object (threat score, VPN/proxy/Tor detection, bot detection)
abuse abuse object (abuse contact info, emails, phone numbers)
user_agent user_agent object (browser, device, OS parsed from the request User-Agent header)
hostname hostname field (reverse DNS lookup)
liveHostname hostname field (live DNS)
hostnameFallbackLive hostname field (fallback to live DNS)
geo_accuracy location.locality , location.accuracy_radius , location.confidence
dma_code location.dma_code
* All optional modules available on your plan

Supported lang values: en , de , ru , ja , fr , cn , es , cs , it , ko , fa , pt


Response Metadata

Every SDK method returns ApiResponse(data=..., metadata=...) .

  • Typed single lookup returns IpGeolocationResponse
  • Typed bulk lookup returns a list of BulkLookupResult
  • Raw methods return the response body as a string
FieldTypeDescription
status_code int HTTP status code
duration_ms int Wall-clock request time in milliseconds, measured by the SDK
credits_charged int or None Parsed from the X-Credits-Charged response header
successful_records int or None Parsed from the X-Successful-Record response header
raw_headers read-only mappingAll response headers. Values are tuples of strings.

Header access helpers:

metadata.header_values("Header-Name")        # all values as a tuple
metadata.first_header_value("Header-Name")   # first value or None

1. JSON Serialization

Use to_json() or to_pretty_json() to serialize SDK objects:

from ipgeolocation import JsonOutputMode, to_pretty_json

# Compact mode (default): omits None fields
print(to_pretty_json(response.data))

# Full mode: includes None fields as null
print(to_pretty_json(response.data, mode=JsonOutputMode.FULL))

Errors

All exceptions inherit from IpGeolocationException . The SDK does not retry failed requests.

Before the request is sent:

  • ValidationException for bad config, invalid request parameters, or calling a closed client

Transport problems:

  • RequestTimeoutException for timeouts
  • TransportException for connection or other HTTP-level failures

API errors (non-2xx responses):

ExceptionHTTP Status
BadRequestException 400
UnauthorizedException 401
NotFoundException 404
MethodNotAllowedException 405
PayloadTooLargeException 413
UnsupportedMediaTypeException 415
LockedException 423
RateLimitException 429
ClientClosedRequestException 499
ServerErrorException 5xx
ApiException Any other non-2xx

All API exceptions have .status_code and .api_message attributes.


Links

Subscribe to Our Newsletter

Get the latest in geolocation tech, straight to your inbox.