Skip to main content

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

Project description

apidepth-python

PyPI Python License: MIT

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.1.tar.gz (41.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.1-py3-none-any.whl (41.5 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: apidepth-0.1.1.tar.gz
  • Upload date:
  • Size: 41.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.1.tar.gz
Algorithm Hash digest
SHA256 ab1f3c5fc81a2fefbbdb47ad38f9251c584027e26929d725397cb48d1f097fa8
MD5 222e5646ecb28701e9ebe06f877e8622
BLAKE2b-256 4f98f9dc7a31be67ebecfade67ed2d9af8c989c1e6b9edfdfee7034c7d378ac9

See more details on using hashes here.

File details

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

File metadata

  • Download URL: apidepth-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 41.5 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.1-py3-none-any.whl
Algorithm Hash digest
SHA256 389ade4333d3b28ace48e549cf347738f88d8db9cdf0645cddf9634b66b91e83
MD5 cd938c49282f338bbf5317e8b6b4ba67
BLAKE2b-256 8b913021cc027cd56c4764b644ffee370b9df0510b90080b9920b128c3302663

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