Python SDK for Recost — automatically tracks outbound HTTP API calls from your application and reports cost, latency, and usage patterns to the Recost dashboard or your local VS Code extension.
Requires Python 3.9+. No core dependencies.
The SDK patches urllib3, httpx, and aiohttp to intercept outbound requests at runtime. It captures metadata only (URL, method, status, latency, byte sizes — never headers or bodies), matches each request against a built-in provider registry, aggregates events into time-windowed summaries, and ships those summaries to the Recost cloud API or the Recost VS Code extension running locally.
Your app
└─ requests.get("https://api.openai.com/v1/chat/completions", ...)
│
▼
Interceptor ← patches urllib3, httpx, aiohttp
│ RawEvent { host, path, method, status_code, latency_ms, ... }
▼
ProviderRegistry ← matches host/path → provider + endpoint_category + cost
│
▼
Aggregator ← buffers events, flushes WindowSummary every 30s
│
▼
Transport
├─ local mode → WebSocket → VS Code extension (port 9847)
└─ cloud mode → HTTPS POST → api.recost.dev
pip install recostWith optional framework and local mode extras:
pip install recost[fastapi] # FastAPI/Starlette middleware
pip install recost[flask] # Flask extension
pip install recost[local] # WebSocket transport for VS Code extension
pip install recost[all] # EverythingNo API key needed. Telemetry goes to the Recost VS Code extension over localhost.
from recost import init
init() # defaults — local mode on port 9847import os
from recost import init, RecostConfig
init(RecostConfig(
api_key=os.environ["RECOST_API_KEY"],
project_id=os.environ["RECOST_PROJECT_ID"],
environment=os.environ.get("PYTHON_ENV", "development"),
))from fastapi import FastAPI
from recost.frameworks.fastapi import RecostMiddleware
app = FastAPI()
app.add_middleware(RecostMiddleware, api_key="...", project_id="...")from flask import Flask
from recost.frameworks.flask import ReCost
app = Flask(__name__)
ReCost(app, api_key="...", project_id="...")Or using the init_app pattern:
recost = ReCost()
recost.init_app(app, api_key="...", project_id="...")All fields are optional. Pass them as keyword arguments or via a RecostConfig instance.
| Option | Type | Default | Description |
|---|---|---|---|
api_key |
str |
— | Recost API key (rc-...). If omitted, runs in local mode. |
project_id |
str |
— | Recost project ID. Required in cloud mode. |
environment |
str |
"development" |
Environment tag attached to all telemetry. |
flush_interval |
float |
30.0 |
Seconds between automatic flushes. |
max_batch_size |
int |
100 |
Early-flush threshold (number of events). |
local_port |
int |
9847 |
WebSocket port for the VS Code extension. |
debug |
bool |
False |
Log telemetry activity to stderr. |
enabled |
bool |
True |
Master kill switch — set False to disable entirely. |
custom_providers |
list[ProviderDef] |
[] |
Extra provider rules with higher priority than built-ins. |
exclude_patterns |
list[str] |
[] |
URL substrings — matching requests are silently dropped. |
base_url |
str |
"https://api.recost.dev" |
Override for self-hosted deployments. |
max_retries |
int |
3 |
Retry attempts for failed cloud flushes. |
on_error |
Callable |
— | Called on internal SDK errors. |
from recost import init, RecostConfig, ProviderDef
init(RecostConfig(
custom_providers=[
ProviderDef(
host_pattern="api.internal.acme.com",
path_prefix="/payments",
provider="acme-payments",
endpoint_category="charge",
cost_per_request_cents=0.5,
),
],
))init() returns a handle with a dispose() method that stops the interceptor, cancels the flush timer, and closes the transport connection.
handle = init(RecostConfig(api_key="..."))
# In a test teardown or shutdown handler:
handle.dispose()import os
from recost import init, RecostConfig
init(RecostConfig(enabled=os.environ.get("PYTHON_ENV") != "test"))Built-in rules ship for the providers below. Cost estimates are rough per-request averages for relative comparison — actual costs vary by model, token count, and region.
| Provider | Host | Tracked endpoints | Cost estimate |
|---|---|---|---|
| OpenAI | api.openai.com |
chat completions, embeddings, image generation, audio transcription, TTS | 0.01–4.0¢/req |
| Anthropic | api.anthropic.com |
messages | 1.5¢/req |
| Stripe | api.stripe.com |
charges, payment intents, customers, subscriptions | 0¢ (% billing) |
| Twilio | api.twilio.com |
SMS, voice calls | 0.79–1.3¢/req |
| SendGrid | api.sendgrid.com |
mail send | 0.1¢/req |
| Pinecone | *.pinecone.io |
vector upsert, query | 0.08¢/req |
| AWS | *.amazonaws.com |
all services (wildcard) | 0¢ (complex pricing) |
| Google Cloud | *.googleapis.com |
all services (wildcard) | 0¢ (complex pricing) |
Unrecognized hosts still appear in telemetry, grouped under "unknown".
Captured:
- Request timestamp, method, URL (query params stripped), host, path
- Response status code
- Round-trip latency (ms)
- Request and response body size (bytes)
- Matched provider, endpoint category, and estimated cost
Never captured:
- Request or response headers (may contain API keys)
- Request or response body content (may contain user data or PII)
from recost import (
RawEvent, # A single intercepted HTTP request
MetricEntry, # Aggregated stats for one provider + endpoint + method
WindowSummary, # Flush payload sent to the API or VS Code extension
RecostConfig, # SDK configuration
ProviderDef, # A custom provider matching rule
TransportMode, # Literal["local", "cloud"]
)pip install -e ".[dev]"
pytest # run all tests
ruff check . # lint
mypy recost/ # type checkAll requests go to https://api.recost.dev. Authentication uses a rc- prefixed API key as Authorization: Bearer {api_key}.
curl -s -X POST https://api.recost.dev/projects/{project_id}/telemetry \
-H "Content-Type: application/json" \
-H "Authorization: Bearer {api_key}" \
-d @payload.json | jq .curl -s "https://api.recost.dev/projects/{project_id}/telemetry/recent?limit=10" \
-H "Authorization: Bearer {api_key}" | jq .curl -s "https://api.recost.dev/projects/{project_id}/analytics?from=2026-01-01T00:00:00Z&to=2026-12-31T23:59:59Z" \
-H "Authorization: Bearer {api_key}" | jq .Licensed under the Business Source License 1.1 © 2026 Andres Lopez, Aslan Wang, Donggyu Yoon. Converts to Apache 2.0 on 2030-04-02.