Skip to main content

Apidepth SDK for Python — track outbound API latency, error rates, and rate limit quota.

Project description

apidepth-python

Track outbound API latency, error rates, and rate limit quota across your third-party vendors — Stripe, OpenAI, Anthropic, Twilio, GitHub, and more.

Zero config for supported vendors. No code changes to your existing HTTP calls.


Installation

pip install apidepth

For requests instrumentation (most common):

pip install "apidepth[requests]"

For httpx instrumentation:

pip install "apidepth[httpx]"

Quick start

Django

Add to INSTALLED_APPS and configure in settings.py:

INSTALLED_APPS = [
    ...
    "apidepth.integrations.django",
]

APIDEPTH = {
    "api_key": env("APIDEPTH_API_KEY"),
    "environment": env("DJANGO_ENV", default="development"),
}

Flask

from flask import Flask
from apidepth.integrations.flask import Apidepth

app = Flask(__name__)
app.config["APIDEPTH_API_KEY"] = os.environ["APIDEPTH_API_KEY"]
app.config["APIDEPTH_ENVIRONMENT"] = "production"

Apidepth(app)

Standalone / scripts

import apidepth
from apidepth import registry_loader

apidepth.configure(
    api_key=os.environ["APIDEPTH_API_KEY"],
    environment="production",
)
apidepth.instrument()       # call before any outbound HTTP
registry_loader.load_and_start()  # loads remote vendor registry + starts refresh thread

import requests
resp = requests.get("https://api.stripe.com/v1/charges/ch_abc123", ...)

load_and_start() fetches the latest vendor registry from the network (with a local disk cache fallback) and starts a background refresh thread. Without it, only the six bundled vendors are recognised. Django and Flask integrations call this automatically.

For Gunicorn / uWSGI, call Collector.register_fork_safety() once before the server forks so each worker gets its own flush thread:

from apidepth.collector import Collector
Collector.register_fork_safety()

Configuration

Option Default Description
api_key None Required. Your Apidepth API key.
environment None Deployment environment tag, e.g. "production".
enabled True Set False to disable all instrumentation.
sample_rate 1.0 Float 0.0–1.0. Fraction of requests to capture.
ignored_hosts [] List of hostnames to never record.
extra_vendors {} Map {"vendor-name": "host"} for in-house APIs.
flush_interval 20 Background flush interval in seconds.
registry_cache_path /tmp/apidepth_registry.json Disk cache for the vendor registry.
registry_refresh_interval 21600 Registry refresh interval in seconds (6 h).
on_flush_error None Callable(exc, ctx) for routing errors to Sentry etc.
collector_url production endpoint Override for self-hosted collectors.

What gets captured

Every outbound HTTP request to a recognised vendor produces one event:

Field Example
vendor "stripe"
endpoint "/v1/charges/:id"
method "POST"
status 200
outcome "success" / "client_error" / "server_error" / "timeout"
duration_ms 234
cold_start false (always — see Known differences)
env "production"
ts 1747008000000 (epoch ms)
rl_remaining 4999 (when rate limit headers present)
rl_limit 5000
rl_reset_at 1747008060000 (epoch ms)

Never captured: request/response bodies, headers, query parameters, credentials.


Supported vendors

Vendor Host
Stripe api.stripe.com
OpenAI api.openai.com
Anthropic api.anthropic.com
Twilio api.twilio.com
Resend api.resend.com
GitHub api.github.com

Additional vendors are loaded from the remote registry every 6 hours.

Custom vendors

apidepth.configure(
    extra_vendors={"payments-api": "api.payments.internal"},
)

Rate limit tracking

The SDK extracts quota state from response headers and includes it in every event. Supported header families (checked in priority order):

  • OpenAI / Anthropic: x-ratelimit-remaining-requests, x-ratelimit-limit-requests, x-ratelimit-reset-requests
  • GitHub: x-ratelimit-remaining, x-ratelimit-limit, x-ratelimit-reset
  • IETF draft / HubSpot: ratelimit-remaining, ratelimit-limit, ratelimit-reset
  • Stripe / generic 429: retry-after

Reset values are normalised to epoch milliseconds regardless of the source format (Unix timestamp, seconds-from-now, OpenAI duration strings like "1m30s").


Debugging

from apidepth.collector import Collector

print(Collector.instance().stats())
# {
#   'queue_size': 0,
#   'consecutive_failures': 0,
#   'total_dropped': 0,
#   'last_flush_at': 1747008000.123,
# }

Framework compatibility

Framework Version Integration
Django 3.2+ apidepth.integrations.django in INSTALLED_APPS
Flask 2.0+ Apidepth(app)
FastAPI / Starlette any Call apidepth.instrument() at startup
Scripts / workers Call apidepth.instrument() at startup

Python compatibility

Python 3.9–3.13. No required runtime dependencies (stdlib only). requests and httpx are optional instrumentation targets detected at runtime.


Known differences from the Ruby gem

cold_start is always false

The Ruby gem tags the first outbound request on each TCP connection with cold_start: true using Net::HTTP#started?. The Apidepth collector uses this flag to exclude DNS + TCP + TLS handshake overhead from latency percentile calculations (p50/p95/p99), keeping those metrics representative of steady-state vendor performance.

Neither requests (backed by urllib3) nor httpx exposes a public API for detecting whether the underlying socket is a keep-alive reuse. The Python SDK therefore always sends cold_start: false.

Practical impact depends on your traffic pattern:

Traffic pattern Impact
High-throughput web service Negligible — cold starts are a tiny fraction of total requests; percentile inflation is unmeasurable
Low-throughput service / cron job Noticeable — the first request per run pays ~50–200 ms of connection overhead that isn't excluded from percentiles; p95/p99 may read slightly higher than in Ruby
Serverless / short-lived worker Material — every invocation starts cold; all latency data includes connection overhead; comparisons against Ruby-instrumented services will show the Python side as systematically higher

The raw duration values are accurate — only the percentile statistics are affected. If cold-start exclusion matters for your environment, filter those events manually in your dashboard (e.g. a warm-up request flag in thread-local state) until the underlying libraries expose the required connection-state API.

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

apidepth-0.1.0.tar.gz (34.9 kB view details)

Uploaded Source

Built Distribution

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

apidepth-0.1.0-py3-none-any.whl (41.4 kB view details)

Uploaded Python 3

File details

Details for the file apidepth-0.1.0.tar.gz.

File metadata

  • Download URL: apidepth-0.1.0.tar.gz
  • Upload date:
  • Size: 34.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.11

File hashes

Hashes for apidepth-0.1.0.tar.gz
Algorithm Hash digest
SHA256 8488e77b0304c9fd854ac0130d2d8535e88e483971087937745a88ddd9eec3dd
MD5 0d158551e5e9d392e15052401546e9be
BLAKE2b-256 cfef4fc9f3c8239ed8e030fe20634c975968d809ac92267f71f255f223789679

See more details on using hashes here.

File details

Details for the file apidepth-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: apidepth-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 41.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.11

File hashes

Hashes for apidepth-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0d3c2c373c738ce903e9d9ad8bfd7459f26aa91ffd6b791037001e50b036ec6c
MD5 6ae8e7da1aeda4e9170769dece9bab0f
BLAKE2b-256 a5731eb4a839053d49a03d6701c157284c8b60e8a16499f551fedcff5698112a

See more details on using hashes here.

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