Skip to main content

OpenAI-compatible LLM proxy with SQLite request capture, observability, and an admin UI.

Project description

LLM Observe Proxy

llm-observe-proxy is an OpenAI-compatible, record-only proxy for inspecting LLM traffic. It forwards requests to an upstream /v1 API, stores requests and responses in SQLite, and provides a polished local admin UI for browsing, pretty-printing, trimming, and changing runtime settings.

It is useful when you want LiteLLM-style observability without introducing a full gateway or external database.

Features

  • OpenAI-compatible passthrough route: ANY /v1/{path:path}.
  • SQLite capture for request/response headers, bodies, status, timing, model, endpoint, streaming state, tool-call signals, image assets, and errors.
  • Admin UI for searching and browsing captured traffic.
  • Detail pages with response render modes for JSON, plain text, Markdown, tool calls, and raw SSE streams.
  • Request image gallery for data URL and remote image references.
  • Settings UI for upstream URL, incoming host/port preferences, all-IPs exposure, and retention trimming.
  • No authentication by default, intended for local or trusted development networks.

Install

After the package is published:

python -m pip install llm-observe-proxy
llm-observe-proxy

For local development from this repository:

C:\Python\Python313\python.exe -m venv .venv
.\.venv\Scripts\python.exe -m pip install -e .[dev]
.\.venv\Scripts\llm-observe-proxy.exe

By default, the proxy listens on:

http://localhost:8080

and forwards requests to:

http://localhost:8000/v1

Open the admin UI:

http://localhost:8080/admin

Usage

Point an OpenAI-compatible client at the proxy:

from openai import OpenAI

client = OpenAI(
    api_key="local-dev-key",
    base_url="http://localhost:8080/v1",
)

response = client.chat.completions.create(
    model="gpt-demo",
    messages=[{"role": "user", "content": "Hello through the proxy"}],
)
print(response.choices[0].message.content)

Run on a different port:

llm-observe-proxy --port 8090

Expose on all interfaces:

llm-observe-proxy --expose-all-ips

Set the upstream from the CLI:

llm-observe-proxy --upstream-url http://localhost:8000/v1

You can also change the upstream URL and next-start incoming host/port settings from /admin/settings.

Screenshots

Screenshots are generated from a seeded demo database and stored in docs/screenshots.

Request browser Tool calls
Request browser Tool-call detail
Images Settings
Image request detail Settings

Additional screenshots:

Regenerate screenshots:

.\.venv\Scripts\python.exe scripts\seed_demo_db.py .tmp\screenshots.sqlite3
.\.venv\Scripts\python.exe scripts\capture_screenshots.py --database .tmp\screenshots.sqlite3 --output docs\screenshots

Routes

  • ANY /v1/{path:path}: OpenAI-compatible pass-through proxy.
  • GET /admin: request browser.
  • GET /admin/requests/{id}: request/response detail view.
  • GET /admin/settings: upstream settings and retention tools.
  • POST /admin/settings/incoming: update incoming host/port settings for next startup.
  • POST /admin/settings/upstream: update upstream URL.
  • POST /admin/trim: delete records older than N days.
  • GET /healthz: health check.

Configuration

Environment variables:

Variable Default Purpose
LLM_OBSERVE_DATABASE_URL sqlite:///./llm_observe_proxy.sqlite3 SQLite SQLAlchemy URL.
LLM_OBSERVE_INCOMING_HOST localhost Bind host when not exposing all IPs.
LLM_OBSERVE_INCOMING_PORT 8080 Bind port.
LLM_OBSERVE_EXPOSE_ALL_IPS false Bind to 0.0.0.0 when true.
LLM_OBSERVE_UPSTREAM_URL http://localhost:8000/v1 Upstream OpenAI-compatible /v1 base URL.
LLM_OBSERVE_LOG_LEVEL INFO Uvicorn log level.

Incoming host/port settings saved in the UI are used on the next process startup; they do not rebind a currently running process.

Tests

.\.venv\Scripts\ruff.exe check src tests
.\.venv\Scripts\python.exe -m compileall -q src tests
.\.venv\Scripts\pytest.exe -q

The test suite starts a fake upstream on localhost:8080/v1, so stop any local process using port 8080 before running tests. See docs/tests/README.md for the full coverage matrix.

Publishing

See docs/publishing.md for name checks, build commands, and the pre-publish checklist.

License

MIT. See LICENSE.

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

llm_observe_proxy-0.1.0.tar.gz (434.3 kB view details)

Uploaded Source

Built Distribution

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

llm_observe_proxy-0.1.0-py3-none-any.whl (25.3 kB view details)

Uploaded Python 3

File details

Details for the file llm_observe_proxy-0.1.0.tar.gz.

File metadata

  • Download URL: llm_observe_proxy-0.1.0.tar.gz
  • Upload date:
  • Size: 434.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.11

File hashes

Hashes for llm_observe_proxy-0.1.0.tar.gz
Algorithm Hash digest
SHA256 f00d36e21602a370be1007055cdc6ac803fde60a3f5681f8d1e05ba4e0cc21db
MD5 bbd611cf7d67d1be4d68f40fe39b040c
BLAKE2b-256 18aeb2b31e717f63d0da187be0ed5588466ffc740a0e338a6a95fbc687a6fe7b

See more details on using hashes here.

File details

Details for the file llm_observe_proxy-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for llm_observe_proxy-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ba28b1b6e6ce5e482c5e1a164dee65baf7ba054a38f1d0f2b360690ef62c1910
MD5 6c84017f354c225c82848c3d406ba7ff
BLAKE2b-256 94ee5b1c252f1d6839f36555c6390bde77673f51ac3dd0e8654e01b1c9b2d40e

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