Skip to content

recost-dev/middleware-python

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

15 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

recost

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.

How it works

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

Installation

pip install recost

With 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]       # Everything

Quick start

Local mode (VS Code extension)

No API key needed. Telemetry goes to the Recost VS Code extension over localhost.

from recost import init

init()  # defaults — local mode on port 9847

Cloud mode

import 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"),
))

FastAPI

from fastapi import FastAPI
from recost.frameworks.fastapi import RecostMiddleware

app = FastAPI()
app.add_middleware(RecostMiddleware, api_key="...", project_id="...")

Flask

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="...")

Configuration

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.

Custom providers

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,
        ),
    ],
))

Cleanup / teardown

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()

Disabling in tests

import os
from recost import init, RecostConfig

init(RecostConfig(enabled=os.environ.get("PYTHON_ENV") != "test"))

Supported providers

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".

What is captured (and what is not)

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)

Core types

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"]
)

Development

pip install -e ".[dev]"
pytest          # run all tests
ruff check .    # lint
mypy recost/    # type check

API reference

All requests go to https://api.recost.dev. Authentication uses a rc- prefixed API key as Authorization: Bearer {api_key}.

Send telemetry (what the SDK does on flush)

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 .

View recent telemetry windows

curl -s "https://api.recost.dev/projects/{project_id}/telemetry/recent?limit=10" \
  -H "Authorization: Bearer {api_key}" | jq .

View analytics

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 .

License

Licensed under the Business Source License 1.1 © 2026 Andres Lopez, Aslan Wang, Donggyu Yoon. Converts to Apache 2.0 on 2030-04-02.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages