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://orbitrage.xyz/api/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://orbitrage.xyz/app/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://orbitrage.xyz/api/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.5.2.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.5.2-py3-none-any.whl (7.9 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: orbitrage-0.5.2.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.5.2.tar.gz
Algorithm Hash digest
SHA256 d473278adc39eb5281c584ea497162fddf8b463e3e0e0b22e7a0964c4fdeaed9
MD5 f308b72e989ab71d318afa34c0c5c315
BLAKE2b-256 1b4170b79b6e0fc15ad344c0405200ba9042960ae08171a79d05782bf5ab00f9

See more details on using hashes here.

File details

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

File metadata

  • Download URL: orbitrage-0.5.2-py3-none-any.whl
  • Upload date:
  • Size: 7.9 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.5.2-py3-none-any.whl
Algorithm Hash digest
SHA256 4e953cfbcaca1e816531e368ccc30e21a97324d75475be0d3ece1ec11545ab4a
MD5 dff52bd4f1ca99836bd4f7237283b696
BLAKE2b-256 b8cc378bba045b0855c4b4cd1aa112ae4ffbe29601d27dd3e604ed019ae981cf

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