SDKs
Markdown

Python SDK

Official IPScope server-side client for Python 3.10+ (asyncio & sync) (ipscope).

# Install

Install
pip install ipscope

# Quickstart: single, batch & prefix lookups

Pass your API key explicitly or set IPSCOPE_KEY in your environment. Every lookup returns the canonical response schema with geo, network, connection, security and security_extensions.

Python
import asyncio
import os
from ipscope import AsyncIpScopeClient

async def main() -> None:
    async with AsyncIpScopeClient(api_key=os.environ["IPSCOPE_KEY"]) as client:
        # 1. Single IPv4 or IPv6 lookup (cached automatically in bounded LRU)
        info = await client.lookup_ip("198.51.100.7")
        print(info["ip"], info["geo"]["country_code"], info["network"]["asn"])
        print("VPN:", info["security"]["is_vpn"], "Reason:", info["security_extensions"]["anonymizer_reason"])

        # 2. Batch lookup (up to 100 IPs; deduplicates & reuses cached entries)
        batch = await client.lookup_batch(["198.51.100.7", "1.1.1.1", "2606:4700:4700::1111"])
        for record in batch["results"]:
            print(record["ip"], "->", record["network"]["organization"])

        # 3. Memory-bounded async streaming for 10,000+ IPs (constant O(chunk) RAM)
        async for chunk in client.lookup_batch_stream(large_ip_list, chunk_size=100):
            for record in chunk["results"]:
                pass  # Process each record with < 350 KB steady-state memory overhead

        # 4. Network CIDR prefix lookup
        prefix = await client.lookup_network("198.51.100.0/24")
        print(prefix["queried_cidr"], prefix["record"]["asn"], prefix["record"]["organization"])

asyncio.run(main())
Responses
application/json

1. Single IPv4/IPv6 lookup response (GET /v1/ip/{ip})

{
  "ip": "198.51.100.7",
  "ip_version": 4,
  "matched_network": "198.51.100.0/24",
  "geo": {
    "country_code": "US",
    "declared_country_code": "US",
    "physical_country_code": "US",
    "is_virtual_location": false,
    "location_type": "physical",
    "confidence": 0.94,
    "subdivision": "Virginia",
    "city": "Ashburn",
    "postal_code": "20147",
    "latitude": 39.0438,
    "longitude": -77.4874,
    "accuracy_radius_km": 10,
    "timezone": "America/New_York"
  },
  "network": {
    "asn": 64501,
    "organization": "Example Cloud LLC"
  },
  "connection": {
    "connection_type": "hosting",
    "is_hosting": true,
    "is_residential": false,
    "is_mobile": false,
    "is_business": false
  },
  "security": {
    "is_vpn": true,
    "is_hosting": true,
    "is_tor_exit": false,
    "is_proxy": false,
    "anonymizer_type": "vpn",
    "confidence": 0.96,
    "reason_codes": [
      "vpn_handshake_confirmed",
      "datacenter_asn_range"
    ]
  },
  "security_extensions": {
    "abuse_velocity_score": 18,
    "is_known_scanner": false,
    "observation_recency_hours": 12,
    "anonymizer_reason": "vpn_handshake_confirmed",
    "threat_level": "medium",
    "abuse_velocity": "low",
    "confidence": 0.96
  },
  "dataset_version": "2026-10-27T00:00:00Z.crawl-1793088000000",
  "updated_at": "2026-10-27T00:00:00Z"
}
application/json

4. Network CIDR prefix lookup response (GET /v1/networks/{prefix}/{length})

{
  "queried_cidr": "198.51.100.0/24",
  "family": 4,
  "dataset_version": "2026-10-27T00:00:00Z.crawl-1793088000000",
  "record": {
    "prefix": "198.51.100.0/24",
    "family": 4,
    "asn": 64501,
    "organization": "Example Cloud LLC",
    "countryCode": "US",
    "city": "Ashburn",
    "locationType": "physical",
    "isVpn": true,
    "isHosting": true,
    "isTorExit": false,
    "isProxy": false,
    "anonymizerType": "vpn"
  }
}

# Architecture & runtime guarantees

  • Ships both AsyncIpScopeClient (httpx.AsyncClient connection pooling) and IpScopeClient (thread-safe sync wrapper).
  • Built-in O(1) bounded LRU cache (max_cache_entries=2048, cache_ttl_seconds=60) with automatic batch deduplication.
  • lookup_batch_stream() yields chunks of 100 IPs lazily via AsyncIterator so 100,000+ IP enrichments run in constant < 350 KB heap memory.
  • Full TypedDict definitions (IpLookupResponse, GeoInfo, SecurityInfo, SecurityExtensionsInfo) for strict mypy and Pyright checking.

# Reading local MMDB files

If you subscribe to a downloadable database, our .mmdb snapshots open directly in standard MaxMind DB readers with sub-microsecond in-memory lookups:

Python (MMDB)
import maxminddb

with maxminddb.open_database("/var/lib/ipscope/ipscope-complete.mmdb") as reader:
    record = reader.get("198.51.100.7")
    print(record["geo"]["country_code"], record["security"]["is_vpn"])

# Plain HTTP fallback

Need to call the REST API without installing a package? Use Python’s standard HTTP client directly:

Python (HTTP)
import os
import httpx

async with httpx.AsyncClient(timeout=5.0) as client:
    res = await client.get(
        "https://api.ipscope.io/v1/ip/198.51.100.7",
        headers={"Authorization": f"Bearer {os.environ['IPSCOPE_KEY']}"},
    )
    res.raise_for_status()
    info = res.json()