Skip to main content

Official Python SDK for CrawlSnap — the data intelligence API platform

Project description

crawlsnap

Official Python SDK for CrawlSnap — a data intelligence platform that delivers structured, on-demand data through fast, typed APIs. Authenticate once and call any CrawlSnap data product, with first-class types, automatic retries, and pagination built in.

  • Idiomatic, fully typed client (httpx + pydantic v2)
  • Sync and async: CrawlSnap or AsyncCrawlSnap — identical surface
  • crawlsnap.init(...) singleton or an explicit client
  • Resource namespacing: crawlsnap.vector_snap.ip(...)
  • Per-API version pinning with a stable default — your calls never silently jump to a new API version
  • Returns typed data; raises typed exceptions — no envelope bookkeeping
  • Built-in retries with exponential backoff, configurable timeout, auto-pagination

Installation

pip install crawlsnap

Requires Python 3.8+.

Authentication

Get an API key (sk-cs-...) from your CrawlSnap dashboard. Provide it either via the environment or explicitly:

export CRAWLSNAP_API_KEY=sk-cs-...
crawlsnap.init()                       # reads CRAWLSNAP_API_KEY
crawlsnap.init(api_key="sk-cs-...")    # or pass it explicitly

The key is sent as Authorization: Bearer sk-cs-.... Treat it like a password.

Quick start

import crawlsnap

crawlsnap.init(api_key="sk-cs-...")

ip = crawlsnap.vector_snap.ip("8.8.8.8")
print(ip.reputation, ip.as_owner, ip.country)

Each call returns the typed enrichment payload directly, and raises a typed exception on failure — you never inspect an is_success envelope yourself.

Async

AsyncCrawlSnap is the awaitable twin of CrawlSnap — same constructor, same resources, same retries and typed errors. Ideal for enriching many indicators concurrently:

import asyncio
from crawlsnap import AsyncCrawlSnap

async def main():
    async with AsyncCrawlSnap(api_key="sk-cs-...") as client:
        ip, dom = await asyncio.gather(
            client.vector_snap.ip("8.8.8.8"),
            client.vector_snap.domain("google.com"),
        )
        print(ip.as_owner, dom.reputation)

        async for subdomain in client.subdo_snap.scan_iter("example.com"):
            print(subdomain)

asyncio.run(main())

Every method is a coroutine; scan_iter is an async generator (use async for).

Resources

Resource Methods Returns
vector_snap url · hash · ip · domain reputation, detections, categories, relationships
pulse_snap url · hash · ip · domain threat-intelligence pulse (and sandbox) summary
subdo_snap scan · scan_iter enumerated subdomains (paginated)
sport_snap channel · channel_schedule · match · country_channels · daily_schedule live football TV listings: channels, schedules, match details
url    = crawlsnap.vector_snap.url("https://example.com")
file   = crawlsnap.vector_snap.hash("44d88612fea8a8f36de82e1278abb02f")
domain = crawlsnap.vector_snap.domain("google.com")

pulse  = crawlsnap.pulse_snap.ip("8.8.8.8")

channel  = crawlsnap.sport_snap.channel("bein-connect-turkey")
schedule = crawlsnap.sport_snap.channel_schedule("bein-connect-turkey")
match    = crawlsnap.sport_snap.match(5542814)
channels = crawlsnap.sport_snap.country_channels("turkey")
day      = crawlsnap.sport_snap.daily_schedule("2026-07-05")  # or datetime.date

Every method takes its lookup value as the first positional argument and accepts raw_response=True (see below).

sport_snap covers live football (soccer) TV listings: TV channel metadata and broadcast rights, channel broadcast schedules, match details with per-country broadcast coverage (score, events, statistics, and lineups for finished matches), country channel directories, and daily schedules grouped by competition. match.status is scheduled, live, or finished and discriminates how much of the payload is populated. Match ids are discovered via daily_schedule and channel_schedule entries.

API versioning

Each CrawlSnap data product is versioned independently, and the version is just a value the SDK puts in the request path — not something baked into your call site. A direct resource call targets that product's stable default version for this SDK release:

crawlsnap.vector_snap.ip("8.8.8.8")        # default VectorSnap version (stable)

The default is pinned per SDK release and never moves on its own: upgrading the SDK does not silently retarget your calls at a newer API version. When a product ships a new version, you opt in explicitly — per product, without touching the others:

crawlsnap.vector_snap.v1.ip("8.8.8.8")     # explicitly VectorSnap v1
crawlsnap.pulse_snap.url("https://x.com")  # unaffected — PulseSnap default

The same applies on an explicit client (client.vector_snap.v1.ip(...)) and on AsyncCrawlSnap. When a product's default version is bumped in a future SDK release, it ships as a deliberate, documented change — so you upgrade at your own pace.

Error handling

Failures raise a typed exception instead of returning an error envelope:

from crawlsnap import (
    NotFoundError, RateLimitError, QuotaExceededError,
    AuthenticationError, CrawlSnapError,
)

try:
    res = crawlsnap.vector_snap.domain("example.com")
except NotFoundError:
    ...                              # 404 — no data for this indicator
except QuotaExceededError as e:
    print(e.message)                 # 402 — out of credits / monthly quota
except RateLimitError as e:
    print(e.retry_after)             # 429 — daily limit; seconds to wait
except AuthenticationError:
    ...                              # 401 — missing / invalid key
except CrawlSnapError as e:          # base class for every SDK error
    print(e)
HTTP Exception Notes
400 BadRequestError invalid indicator
401 AuthenticationError missing / invalid key
402 QuotaExceededError out of credits or monthly quota
403 SubscriptionInactiveError subscription not active
404 NotFoundError no data for the indicator
429 RateLimitError daily limit; .retry_after (seconds)
5xx ServerError server / upstream failure
APIConnectionError / APITimeoutError network failure / client timeout

Every status error carries .status_code, .message, and .request_id (share the request id with support to speed up debugging).

Pagination

subdo_snap is paginated. Stream every subdomain across all pages — the cursor is handled for you:

for subdomain in crawlsnap.subdo_snap.scan_iter("example.com"):
    print(subdomain)

Or page manually:

page = crawlsnap.subdo_snap.scan("example.com")
while page.cursor:
    page = crawlsnap.subdo_snap.scan("example.com", cursor=page.cursor)

Configuration

The singleton is a thin layer over the CrawlSnap client. For multiple keys, multiple environments, or thread isolation, instantiate it directly:

from crawlsnap import CrawlSnap

client = CrawlSnap(
    api_key="sk-cs-...",
    timeout=30.0,
    max_retries=3,
    base_url="https://api.crawlsnap.com",
)
ip = client.vector_snap.ip("1.1.1.1")
client.close()

AsyncCrawlSnap accepts the exact same options (api_key, base_url, timeout, max_retries); await client.close() or use async with.

Option Default Description
api_key $CRAWLSNAP_API_KEY Your sk-cs- key
base_url $CRAWLSNAP_BASE_URL or https://api.crawlsnap.com API host override
timeout 30.0 Per-request timeout (seconds)
max_retries 2 Retries for 429 / 5xx / connection errors

Retries use exponential backoff and honor the Retry-After header on 429.

Raw response

Pass raw_response=True to get the full envelope (status, headers, request id) instead of just the data:

raw = crawlsnap.vector_snap.ip("8.8.8.8", raw_response=True)
print(raw.status_code, raw.request_id, raw.is_success, raw.data)

Development

The typed models under crawlsnap/models/ are generated from the public OpenAPI contract; the client facade is hand-written. To refresh the models after the contract changes:

./scripts/regenerate.sh        # re-bundles the contract and regenerates models/

Run the tests:

pip install -e ".[dev]"
pytest

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

crawlsnap-0.5.0.tar.gz (31.8 kB view details)

Uploaded Source

Built Distribution

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

crawlsnap-0.5.0-py3-none-any.whl (132.1 kB view details)

Uploaded Python 3

File details

Details for the file crawlsnap-0.5.0.tar.gz.

File metadata

  • Download URL: crawlsnap-0.5.0.tar.gz
  • Upload date:
  • Size: 31.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for crawlsnap-0.5.0.tar.gz
Algorithm Hash digest
SHA256 4156fd6990c51576b68b1e85288e2544ed0f1b9082ed751caf1ff09329690cc7
MD5 b78151ab251c7e7620c7882e2d6c9580
BLAKE2b-256 0e00fa2b4530c3466e52805704b79657289639b1f1460f6f79c6075643cbfb39

See more details on using hashes here.

Provenance

The following attestation bundles were made for crawlsnap-0.5.0.tar.gz:

Publisher: release.yml on crawlsnap/crawlsnap-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file crawlsnap-0.5.0-py3-none-any.whl.

File metadata

  • Download URL: crawlsnap-0.5.0-py3-none-any.whl
  • Upload date:
  • Size: 132.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for crawlsnap-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 45f6cc10854cd12e3e0a7911fa376386d44c502e000d8d5ffcf3007bc8ca4980
MD5 20ad78aa2206aa3cbafd05df04d632c8
BLAKE2b-256 a2a6dee970162569a47d839459aa7e6118b02976041a05ec66d6623cb8901cb7

See more details on using hashes here.

Provenance

The following attestation bundles were made for crawlsnap-0.5.0-py3-none-any.whl:

Publisher: release.yml on crawlsnap/crawlsnap-python

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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