Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Check-Host/python-lib

Repository files navigation

check-host-api

A lightweight, zero-dependency Python 3.10+ SDK for the Check-Host.cc API.

Distributed network diagnostics from 60+ global locations: ICMP ping, MTR, DNS, HTTP, TCP, UDP, WHOIS and geolocation, with the same fluent surface as the official nodejs-lib, php-lib, go-lib and CheckHost4J — plus a few extras specific to Python.

Full API reference: https://check-host.cc/docs.

Highlights

  • Zero runtime dependencies — built on top of urllib.request.
  • Full Swagger 2.0.0 parity — every endpoint covered, including /myinfo, /report/{uuid}/og-image and /report/{uuid}/country-map.
  • Type hints throughout with a PEP 561 py.typed marker.
  • POST-based requests — no URL-encoding pitfalls.
  • Built-in polling helper wait_for_report() so you don't have to babysit the report endpoint by hand.
  • Automatic API-key injection from the constructor or the CHECK_HOST_API_KEY environment variable.
  • Granular exception hierarchy — separate classes for 400, 404, 429 and 5xx.
  • Client-side validation for ports, DNS record types, MTR repeats etc.
  • OG-Image and country-map fetch + save helpers for status maps.
  • Region / DNS-type / MTR-protocol constants for IDE autocompletion.
  • Context-manager support (with CheckHost() as ch: ...).

Installation

pip install check-host-api

Requires Python 3.10+. No further dependencies.

Quickstart

from checkhost import CheckHost
from checkhost.regions import Continent, DNSType
with CheckHost() as ch:
 # Geolocation / ASN
 info = ch.info("check-host.cc")
 print(f"{info.ip} -> {info.city}, {info.country} ({info.asn.get('name')})")
 # Ping check across Europe + North America, 3 packets per node
 task = ch.ping(
 "1.1.1.1",
 region=[Continent.EUROPE, Continent.NORTH_AMERICA],
 repeat_checks=3,
 )
 print(f"Task UUID: {task.uuid}")
 # Block until every node reports (or 20s elapses)
 report = ch.wait_for_report(task.uuid, max_wait=20.0)
 print(f"{len(report.completed_nodes)} nodes reported")
 # Save the dynamic status map (PNG, 1200x630) and country world map
 ch.save_og_image(task.uuid, "./status.png")
 ch.save_country_map(task.uuid, "./status.svg")

Authentication

The API works without a key (subject to public rate limits). For higher limits, provide an API key (UUID) via constructor or environment variable:

ch = CheckHost("YOUR_API_KEY_UUID")
# or
import os
os.environ["CHECK_HOST_API_KEY"] = "YOUR_API_KEY_UUID"
ch = CheckHost()

When both are present, the constructor argument wins.

Complete API Reference & Examples

This SDK supports both minimal invocations and detailed, options-rich requests for every endpoint.

Common Options

  • region: list of node names, ISO country codes, or continent codes (EU, NA, SA, AS, AF, OC). Continents cannot be mixed with specific node names.
  • repeat_checks: number of repeated probes per node. 0 = single shot; >= 10 enables Live Mode (continuous probing for ~repeat_checks seconds).
  • timeout: per-request connection timeout in seconds (currently a no-op on the Check-Host backend, but accepted for forward compatibility).

Information & Utilities

Get my IP

Returns the requesting client's public IPv4 / IPv6 address.

ip = ch.myip()

Get my info

Geolocation + ASN + privacy / abuse / company data for the caller's IP. Subject to bot-detection — repeated calls may yield a captcha URL in a CheckHostRateLimitError.response.

info = ch.myinfo()
print(info.country_code, info.city, info.asn.get("name"))

List monitoring nodes

locations = ch.locations()
# locations["locationlist"] is a list of nodes, each with continent,
# countryCode, isp, locationname, sponsor, etc.

Host info (geolocation / ASN)

info = ch.info("check-host.cc")

WHOIS / RDAP lookup

record = ch.whois("check-host.cc")
# Returns the raw RDAP record (shape varies by registry).

Active Monitoring (POST tasks)

Each monitoring call returns a CheckCreated object with a uuid. Use report(uuid) (single fetch) or wait_for_report(uuid) (polling helper) to retrieve results.

Ping

# Minimal
task = ch.ping("8.8.8.8")
# With options
task = ch.ping(
 "8.8.8.8",
 region=["DE", "NL"],
 repeat_checks=5, # >=10 enables Live Mode
 timeout=5,
)

DNS

from checkhost.regions import DNSType
# Minimal — defaults to A record
task = ch.dns("check-host.cc")
# Specific record type
task = ch.dns(
 "check-host.cc",
 query_method=DNSType.MX, # A / AAAA / MX / TXT / NS / CAA / ...
 region=["US", "DE"],
)

TCP

# Minimal — host + port
task = ch.tcp("1.1.1.1", 443)
# With options
task = ch.tcp(
 "1.1.1.1",
 80,
 region=["DE", "NL"],
 repeat_checks=3,
 timeout=10,
)

UDP

The Check-Host backend knows sensible default payloads for well-known ports (DNS, NTP, SNMP, RIP, WireGuard, OpenVPN, Quake, Minecraft, ...). Pass a custom hex (or printable) payload only when probing unusual services.

# Minimal — DNS query (default payload)
task = ch.udp("1.1.1.1", 53)
# Custom NTP payload to UDP/123
task = ch.udp(
 "pool.ntp.org",
 123,
 payload="0b",
 region=["EU"],
 repeat_checks=2,
)

HTTP

# Minimal — full URL
task = ch.http("https://check-host.cc")
# With options
task = ch.http(
 "https://check-host.cc/status",
 region=["EU"],
 repeat_checks=10, # Live Mode: 11 probes over ~10s
)

MTR (My Traceroute)

from checkhost.regions import MTRProtocol, IPVersion
# Minimal
task = ch.mtr("1.1.1.1")
# Force TCP for ICMP-blocked paths
task = ch.mtr(
 "1.1.1.1",
 region=["EU"],
 repeat_checks=10,
 force_ip_version=IPVersion.V4,
 force_protocol=MTRProtocol.TCP, # "udp" or "tcp"; default is ICMP
)

Results

Single fetch

report = ch.report(task.uuid)
print(report.is_complete, len(report.completed_nodes), report.pending_nodes)

Poll until complete

report = ch.wait_for_report(
 task.uuid,
 interval=1.5, # clamped to >=1.0 (API limit)
 max_wait=30.0,
 require_complete=True, # raise CheckHostTimeoutError on timeout
)
png_bytes = ch.og_image(task.uuid)
# Or write straight to disk
ch.save_og_image(task.uuid, "./status.png")

Country world map (SVG or PNG)

svg = ch.country_map(task.uuid) # default SVG
png_low = ch.country_map(task.uuid, format="png", resolution="low") # 800px
png_high = ch.country_map(task.uuid, format="png", resolution="high") # 2000px
# Convenience save
ch.save_country_map(task.uuid, "./status.svg")

API surface (reference table)

Method Endpoint Returns
ch.myip() GET /myip str
ch.myinfo() GET /myinfo MinResponseINFO
ch.locations() GET /locations dict[str, Any]
ch.info(target) POST /info MinResponseINFO
ch.whois(target) POST /whois dict[str, Any]
ch.ping(target, *, region=None, repeat_checks=0, timeout=None) POST /ping CheckCreated
ch.dns(target, *, query_method="A", region=None) POST /dns CheckCreated
ch.tcp(target, port, *, region=None, repeat_checks=0, timeout=None) POST /tcp CheckCreated
ch.udp(target, port, *, payload=None, region=None, repeat_checks=0, timeout=None) POST /udp CheckCreated
ch.http(target, *, region=None, repeat_checks=0, timeout=None) POST /http CheckCreated
ch.mtr(target, *, region=None, repeat_checks=10, force_ip_version=None, force_protocol=None) POST /mtr CheckCreated
ch.report(uuid) GET /report/{uuid} Report
ch.wait_for_report(uuid, *, interval=1.5, max_wait=30.0, require_complete=True) polls GET /report/{uuid} Report
ch.og_image(uuid) GET /report/{uuid}/og-image bytes (PNG)
ch.save_og_image(uuid, path) same Path
ch.country_map(uuid, *, format="svg", resolution="med") GET /report/{uuid}/country-map bytes
ch.save_country_map(uuid, path, *, format="svg", resolution="med") same Path

Client-side validation

The SDK rejects obviously bad input before issuing an HTTP call:

  • port: 1-65535
  • repeat_checks (non-MTR): 0-120
  • repeat_checks (MTR): 3-30
  • query_method: one of A, AAAA, MX, TXT, CAA, A/AAAA, ... (full list in checkhost.regions.DNSType.ALL)
  • force_ip_version: 4 or 6
  • force_protocol: "icmp" | "udp" | "tcp"
  • country_map.format: "svg" | "png"
  • country_map.resolution: "low" | "med" | "high"

Use report.completed_nodes, report.pending_nodes and report.is_complete to inspect progress; report.raw always preserves the raw API payload, including any future fields the SDK doesn't yet surface explicitly.

Constants

from checkhost.regions import Continent, DNSType, IPVersion, MTRProtocol
Continent.EUROPE # "EU"
Continent.ALL # ("EU", "NA", "SA", "AS", "AF", "OC")
DNSType.MX # "MX"
DNSType.A_AAAA # "A/AAAA" - Swagger 2.0 compound default
DNSType.ALL # ("A/AAAA", "A", "AAAA", "NS", ..., "DNSKEY")
IPVersion.V4 # 4
MTRProtocol.TCP # "tcp"

Error handling

from checkhost import (
 CheckHost,
 CheckHostBadRequestError,
 CheckHostError,
 CheckHostNetworkError,
 CheckHostRateLimitError,
 CheckHostTimeoutError,
 CheckHostValidationError,
)
with CheckHost() as ch:
 try:
 task = ch.ping("1.1.1.1")
 report = ch.wait_for_report(task.uuid, max_wait=15.0)
 except CheckHostValidationError as exc:
 # Invalid input - fix the call.
 ...
 except CheckHostRateLimitError as exc:
 # 429: provide an API key or back off.
 ...
 except CheckHostBadRequestError as exc:
 # 400: bad payload.
 print(exc.status, exc.response)
 except CheckHostTimeoutError:
 # Polling deadline expired.
 ...
 except CheckHostNetworkError:
 # Connectivity / DNS / TLS issue.
 ...
 except CheckHostError:
 # Catch-all for the SDK.
 ...

Hierarchy at a glance:

CheckHostError
+-- CheckHostNetworkError
+-- CheckHostTimeoutError
+-- CheckHostValidationError (also ValueError)
+-- CheckHostAPIError
 +-- CheckHostBadRequestError (400)
 +-- CheckHostNotFoundError (404)
 +-- CheckHostRateLimitError (429)
 +-- CheckHostServerError (5xx)

Logging

The SDK uses the standard logging module under the logger name "checkhost". Enable debug logs to inspect every outgoing HTTP request:

import logging
logging.basicConfig(level=logging.DEBUG)
logging.getLogger("checkhost").setLevel(logging.DEBUG)

Proxies and TLS

urllib.request from the standard library is used, which means HTTP_PROXY / HTTPS_PROXY / NO_PROXY environment variables are honoured automatically and TLS verification follows the system trust store.

Development

git clone https://git.check-host.eu/Check-Host/python-lib
cd python-lib
pip install -e ".[dev]"
pytest # 155 unit tests, ~0.2s
ruff check . && mypy checkhost

To run the integration tests against the live API (consumes real rate-limit budget — set CHECK_HOST_API_KEY for higher quotas):

pytest -m live # 8 live tests, ~6s with an API key

License

Apache-2.0

Related libraries

Full API reference: https://check-host.cc/docs.

About

Official zero-dependency Python 3.10+ SDK for the Check-Host.cc API. Distributed network diagnostics (ping, MTR, DNS, HTTP, TCP, UDP, WHOIS) from 60+ global locations.

Topics

Resources

License

Stars

Watchers

Forks

Packages

Contributors

Languages

AltStyle によって変換されたページ (->オリジナル) /