Skip to main content

One-line observability + intelligent LLM routing for Python agents.

Project description

orbitrage

One LLM gateway. Router + observability. One line.

Orbitrage is the proxy between your code and the model providers. Every request flows through it — so it sees the model you asked for, the model it routed to, the input messages, the output, tokens, cost, and latency. Pointing your OpenAI SDK at https://api.orbitrage.ai/v1 is the entire integration; this package is a 5-line convenience wrapper that does it for you and tags every call with a trace + user id so the dashboard groups them properly.

import orbitrage
orbitrage.init("orb_xxx_yyy")           # 1 line of setup
                                         #
from openai import OpenAI                # 2 lines of usage — the SDK auto-points
client = OpenAI()                        #   at the Orbitrage gateway and adds
                                         #   trace headers to every request.
client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "hi"}],
)

Open https://app.orbitrage.ai/workflows — every call shows up with model, tokens, cost, latency, and the full input/output.

Install

pip install orbitrage

The only runtime dependency is the Python standard library. openai and anthropic are optional peers — install whichever clients you use.

What init() does

  1. Generates a stable trace id for this process. Every request from this process carries it as x-orbitrage-run-id, so the dashboard groups all your agent's LLM calls into a single run.
  2. Patches the OpenAI and Anthropic client constructors to default base_url to https://api.orbitrage.ai/v1 and add the trace headers via default_headers. If you already set base_url or api_key explicitly, your value wins.
  3. Sets the OPENAI_BASE_URL env var as a safety net for code that constructs the client without any args.

That's all. No background threads, no span processors, no OTLP exports. The gateway sees every byte of the request and writes the routing decision, the upstream response, tokens, cost, and latency directly to your project's data store. The proxy is the single source of truth.

Per-end-user graphs

If you're a B2B service handling traffic for many end-users (your customers' users), pass user_id so the dashboard can partition every call inside one workflow:

orbitrage.init("orb_xxx", user_id=current_user.id)

Every subsequent LLM call is tagged with x-orbitrage-end-user-id. The dashboard uses it to build per-user flow graphs, cost breakdowns, and churn signals.

For long-running servers that switch end-users between requests, call orbitrage.set_user(user_id) at the start of each request. The next OpenAI or Anthropic client constructed after that picks up the new id.

Bring your own provider key (BYOK)

Save your OpenAI / Anthropic / Google / Groq key on the Models page. For models that match that provider, Orbitrage forwards the request to the provider with your key — your account is billed, our pooled credits are untouched. Routing decisions still appear in your dashboard with byok=true so you can see the split.

Forcing a specific model

Pass the model id verbatim — Orbitrage routes by explicit pin when the caller names a model:

client.chat.completions.create(
    model="claude-sonnet-4-6",     # explicit pin, no scoring
    messages=[...],
)

To let the router pick the cheapest model that meets the prompt's difficulty, pass the alias auto (or any of router, default, orbitrage).

Backward compatibility

Functions kept as no-op shims for code written against v0.4:

@orbitrage.workflow("checkout")
def run(): ...

@orbitrage.task("plan")
def plan(): ...

orbitrage.flush()       # no-op — the gateway persists synchronously
orbitrage.shutdown()    # no-op

These return the wrapped function untouched. The router captures the same data regardless of decorator markup; the decorators exist so v0.4 user code keeps importing without errors.

How the workflow is determined

Every API key is minted for one workflow from the dashboard. The workflow your calls land under is whichever workflow your key belongs to — no app_name argument required.

License

Apache-2.0

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

orbitrage-0.6.0.tar.gz (9.8 kB view details)

Uploaded Source

Built Distribution

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

orbitrage-0.6.0-py3-none-any.whl (8.2 kB view details)

Uploaded Python 3

File details

Details for the file orbitrage-0.6.0.tar.gz.

File metadata

  • Download URL: orbitrage-0.6.0.tar.gz
  • Upload date:
  • Size: 9.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.5

File hashes

Hashes for orbitrage-0.6.0.tar.gz
Algorithm Hash digest
SHA256 cd09eb9d704b9d332075b3b3fd81bbed3309be94a1839dcd45ff0c5fa322ef9e
MD5 ac13f5c238b666980c62c396f1efde99
BLAKE2b-256 f78b6ff4b50eb5105e19d71e9847559bbd50aeddcc094c7936ef3a6e31a7b210

See more details on using hashes here.

File details

Details for the file orbitrage-0.6.0-py3-none-any.whl.

File metadata

  • Download URL: orbitrage-0.6.0-py3-none-any.whl
  • Upload date:
  • Size: 8.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.5

File hashes

Hashes for orbitrage-0.6.0-py3-none-any.whl
Algorithm Hash digest
SHA256 708df08f8fe0605c63cd6e753a12b89aef2e2008d4fc863a46e71b0d1cbfc56c
MD5 58e1d80b78a274f065b24264178a77ce
BLAKE2b-256 69cf26bc3d6789f14b5486d916cbb011ae03d34b146546f4c477432e06f473d6

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