Skip to main content

LLM Gateway with Anthropic-compatible API

Project description

TTLLM Gateway

LLM gateway exposing an Anthropic-compatible API (POST /v1/messages), routing requests through LangChain to any supported provider (Bedrock, OpenAI, etc.). Tracks tokens, costs, and maintains audit trails. Supports user management with per-user model access control.

Quick Start

Prerequisites

  • Python 3.12+
  • PostgreSQL 16
  • Docker (optional)

Run with Docker Compose

docker-compose up

This starts PostgreSQL and the API on port 8000. Migrations run automatically on container start.

A default admin account is created by the migrations:

  • Email: admin@localhost
  • Password: value of TTLLM_ADMIN_PASSWORD (defaults to admin)

Set TTLLM_ADMIN_PASSWORD before running migrations to use a custom password. Log in via ttllm login and change the password or create a new admin user immediately.

Run from Docker Image

# From GitHub Container Registry
docker run -p 8000:8000 \
  -e TTLLM_DATABASE__URL="postgresql+asyncpg://user:pass@host:5432/ttllm" \
  ghcr.io/ponquersohn/ttllm-gateway:latest

Passing configuration

Option A - Mount a config file:

docker run -p 8000:8000 \
  -v /path/to/config.yaml:/app/config.yaml \
  -e TTLLM_CONFIG_FILE=/app/config.yaml \
  -e TTLLM_CONFIG_ENV=prod \
  ghcr.io/ponquersohn/ttllm-gateway:latest

Option B - Environment variables only:

docker run -p 8000:8000 \
  -e TTLLM_DATABASE__URL="postgresql+asyncpg://user:pass@host:5432/ttllm" \
  -e TTLLM_AUTH__JWT__SECRET_KEY="your-secret" \
  -e TTLLM_ENGINE__LISTEN_PORT=8000 \
  -e TTLLM_PROVIDER__DEFAULT_REGION="us-east-1" \
  ghcr.io/ponquersohn/ttllm-gateway:latest

The container listens on port 8000 by default (configurable via engine.listen_port). Map it to any host port with -p <host>:<container>.

Debugging failed containers

By default the container exits on error. Set TTLLM_EXIT_ON_ERROR=false to keep the container alive after a failure, so you can exec into it for debugging:

docker run -p 8000:8000 \
  -e TTLLM_EXIT_ON_ERROR=false \
  -e TTLLM_DATABASE__URL="postgresql+asyncpg://user:pass@host:5432/ttllm" \
  ghcr.io/ponquersohn/ttllm-gateway:latest

Install from PyPI

pip install ttllm-gateway

Run Locally

pip install -e .
alembic upgrade head
uvicorn ttllm.handlers.ecs_entrypoint:app --reload

Configuration

Settings are resolved in order: YAML config file -> environment variables -> defaults.

Environment Variable Description Default
TTLLM_CONFIG_FILE Path to YAML config file (none)
TTLLM_CONFIG_ENV Environment section to load dev
TTLLM_DATABASE__URL PostgreSQL connection string postgresql+asyncpg://ttllm:dev@localhost:5432/ttllm
TTLLM_ENGINE__LISTEN_PORT Server listen port 8000
TTLLM_ENGINE__BASE_URL External-facing URL (for OAuth callbacks) http://localhost:4000
TTLLM_ENGINE__CORS_ORIGINS Allowed CORS origins ["*"]
TTLLM_AUTH__JWT__SECRET_KEY JWT signing secret CHANGE-ME-IN-PRODUCTION
TTLLM_PROVIDER__DEFAULT_REGION AWS region for Bedrock us-east-1
TTLLM_SECRETS__ENCRYPTION_KEY Fernet key for encrypting secrets (none)

Nested env vars use __ as delimiter. YAML values support env://VAR,default and secret://arn resolution patterns. Local overrides via local.config.yaml (git-ignored).

Config file example

dev:
  database:
    url: "postgresql+asyncpg://ttllm:dev@localhost:5432/ttllm"
    pool_size: 5
  engine:
    base_url: "http://localhost:8000"
    listen_port: 8000
    cors_origins: ["*"]
    log_request_bodies: false
  auth:
    jwt:
      secret_key: "dev-secret"
      algorithm: "HS256"
      access_token_ttl_minutes: 15
    identity_providers:
      entra:
        name: "Entra ID"
        type: "oidc"
        client_id: "..."
  provider:
    default_region: "us-east-1"
  secrets:
    encryption_key: "env://TTLLM_SECRETS_ENCRYPTION_KEY"

Secrets Management

Provider credentials (AWS keys, API keys, etc.) can be stored encrypted in the database and referenced from model configs using secret://name. This avoids storing plaintext credentials in config_json.

Setup

  1. Generate an encryption key and add it to your config:
python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"

Add to config.yaml:

dev:
  secrets:
    encryption_key: "your-generated-key"

Or via environment variable: TTLLM_SECRETS__ENCRYPTION_KEY.

  1. Create secrets:
ttllm secrets create --name aws-bedrock-key        # prompts for value (hidden)
ttllm secrets create --name aws-bedrock-secret      # prompts for value (hidden)
  1. Reference secrets in model config:
ttllm models create \
  --name claude-sonnet \
  --provider bedrock \
  --provider-model-id anthropic.claude-3-sonnet-20240229-v1:0 \
  --config '{"aws_access_key_id":"secret://aws-bedrock-key","aws_secret_access_key":"secret://aws-bedrock-secret","region":"us-west-2"}'

At runtime, secret:// references are resolved transparently before the provider client is created. Secret values are never exposed through the API or CLI.

CLI

Admin operations via the ttllm CLI:

ttllm users list|show|create|update|delete
ttllm models list|show|create|update|delete|assign|unassign
ttllm groups list|show|create|update|delete
ttllm tokens list|show|create|delete
ttllm secrets list|show|create|update|delete
ttllm usage summary|costs [--user] [--model] [--since] [--until]
ttllm audit-logs [--user] [--model] [--limit]

Releasing

Releases are created from the main branch. The Makefile bumps the version in src/ttllm/__init__.py and shows the commands to complete the release:

make release         # Patch bump (v0.0.1 -> v0.0.2)
make release-minor   # Minor bump (v0.1.0 -> v0.2.0)
make release-major   # Major bump (v1.0.0 -> v2.0.0)

After running make release*, follow the printed instructions to commit, tag, push, and create the GitHub release. Publishing a GitHub release triggers the CI workflow to:

  1. Validate that the git tag matches the __version__ in code
  2. Publish the Python package to PyPI
  3. Build and push the Docker image to ghcr.io/ponquersohn/ttllm-gateway

Development

pip install -e ".[dev]"
pytest

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

ttllm_gateway-0.0.9.tar.gz (61.4 kB view details)

Uploaded Source

Built Distribution

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

ttllm_gateway-0.0.9-py3-none-any.whl (59.9 kB view details)

Uploaded Python 3

File details

Details for the file ttllm_gateway-0.0.9.tar.gz.

File metadata

  • Download URL: ttllm_gateway-0.0.9.tar.gz
  • Upload date:
  • Size: 61.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for ttllm_gateway-0.0.9.tar.gz
Algorithm Hash digest
SHA256 604deaa383f9ac133b47f4d5adb05f391766b9a9ba3786a6796b64eea518a67e
MD5 8daf195e8668bcd23fa1d316cb60348e
BLAKE2b-256 1efaa2618e8804c04136c1ac10a173296d67c42d02a677c8a9305832f3930c66

See more details on using hashes here.

Provenance

The following attestation bundles were made for ttllm_gateway-0.0.9.tar.gz:

Publisher: release.yml on ponquersohn/ttllm-gateway

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ttllm_gateway-0.0.9-py3-none-any.whl.

File metadata

  • Download URL: ttllm_gateway-0.0.9-py3-none-any.whl
  • Upload date:
  • Size: 59.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for ttllm_gateway-0.0.9-py3-none-any.whl
Algorithm Hash digest
SHA256 3d018bc819b09147e9370a4ed80bc9b8ef5dac225c474393e3e8f909eee8f9db
MD5 97dced02e78540adac2dd223786a6204
BLAKE2b-256 f2ca44232eec752291d04d7df04faf4e86b7ad66302da0f879a62c998754728c

See more details on using hashes here.

Provenance

The following attestation bundles were made for ttllm_gateway-0.0.9-py3-none-any.whl:

Publisher: release.yml on ponquersohn/ttllm-gateway

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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