Skip to main content

IPGeolocation.io Python SDK

Typed Python SDK for the IPGeolocation.io IP Geolocation 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.10+

Table of Contents

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)

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: API key authentication supports single lookups on all plans. Bulk lookup requires a paid plan.

config = IpGeolocationClientConfig(api_key="YOUR_API_KEY")

Client Config

Field Use
api_key API key auth for single lookup and bulk lookup
base_url Use the final address of your API or proxy. The standard client follows redirects only if the protocol, host and port stay the same. The async client stops at redirects by default.
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.

Capabilities

Capability Free Paid
Single IPv4/IPv6 lookup Yes Yes
Domain lookup No Yes
Bulk lookup (/v3/ipgeo-bulk) No Yes
Non-English lang No Yes
Optional modules via include No Yes
include=["*"] Base response only All plan-available modules

Default Response Sections

Default single-lookup response:

Section Free Paid
location Yes Yes
country_metadata Yes Yes
currency Yes Yes
asn (basic: as_number, organization, country) Yes Yes
asn (full: adds type, domain, date_allocated, rir) No Yes
time_zone Yes Yes
network No Yes
company No Yes

Examples

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

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

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"

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])

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)

Note: The user_agent field on the request model is different. It overrides the outbound User-Agent header for the HTTP request itself and takes precedence over headers["User-Agent"]. If you set both, the API parses the user_agent value.

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)

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

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

Single Lookup

Field Type Notes
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 strings Optional modules to enable. See include values.
fields sequence of strings Response field filter. Does not unlock data.
excludes sequence of strings Response 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 strings Custom request headers. Accept is always SDK-managed. Sequence values are sent as one comma-joined header line.

Bulk Lookup

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

Field Type Notes
ips sequence of strings Required. Up to 50,000 IPs or domains.

Set api_key in your client settings for bulk lookups. The SDK sets Content-Type: application/json for you.

include Values

Value What 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, ar (Arabic)

Response Metadata

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

  • Typed single lookup returns IpGeolocationResponse
  • A typed bulk lookup returns one BulkLookupResult per input. If the API sends too few or too many results, the SDK raises SerializationException.
  • Raw methods return the response body as a string
Field Type Description
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 mapping All 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

JSON Serialization

Use to_json() or to_pretty_json() to print SDK objects as JSON. When you print your client settings, the SDK hides your API key.

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):

Exception HTTP 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. If the error body is too large or the connection closes early, you still get the HTTP status. The SDK hides your API key in error messages, including errors for individual IPs in a typed bulk lookup.

Metadata

Release files for ipgeolocationio 3.0.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ipgeolocationio 3.0.1
File Size Uploaded Provenance Actions
ipgeolocationio-3.0.1.tar.gz 56.4 kB Without provenance Details for ipgeolocationio-3.0.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for ipgeolocationio 3.0.1
File Interpreter ABI Platform Actions
ipgeolocationio-3.0.1-py3-none-any.whl Python 3 none any Details for ipgeolocationio-3.0.1-py3-none-any.whl

Total release size: 87.9 kB

Release files / ipgeolocationio-3.0.1.tar.gz

Download URL ipgeolocationio-3.0.1.tar.gz
Size 56.4 kB
Tags Source
SHA-256 checksum
How to use checksums
e8c2e3a891c8a12bd634c1bad3fa481637547cc2a23f377f7e67b32eea9c33aa
BLAKE2b-256 checksum
How to use checksums
ced3543e33ca7d9071028c44212e33265b40ef7aa4823ef944928e81802573bb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.16

Release files / ipgeolocationio-3.0.1-py3-none-any.whl

Download URL ipgeolocationio-3.0.1-py3-none-any.whl
Size 31.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3ae507c860b648f6cf274e61a02a06342f6c5335f3d03f17563c75187a893e18
BLAKE2b-256 checksum
How to use checksums
fbc18c1149c496060be42cb8fee1284004a18033b293d269919ae0b2825a651e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.16

Security for ipgeolocationio 3.0.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page