Oliver Hofmann c8235ec274 Refactor to flat APIKey model with quota, admin UI, .env config, and Berlin timezone
- Remove User/Quota models; quota fields now live directly on APIKey
- Admin UI: login, API key management, settings (Ollama URL/model), proxy info display
- .env/.env.example: ADMIN_PASSWORD, PROXY_HOST/PORT, DATABASE_URL, APP_TZ
- Admin API runs on 127.0.0.1 only; proxy host/port configurable
- API keys support optional expires_at; verified against Europe/Berlin timezone
- Daily/monthly quota resets use Europe/Berlin midnight boundary
- Fix all tests to use new flat model; add expiry tests

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 08:21:42 +02:00
2026-04-27 18:54:27 +02:00
2026-04-27 18:54:27 +02:00
2026-04-27 18:54:27 +02:00

Ollama Proxy mit API-Keys und Quotas

Ein Reverse-Proxy für Ollama mit API-Key-Authentifizierung und Quota-Management.

Features

  • API-Key-Authentifizierung (Bearer Token oder sk--Prefix)
  • Quota-Management mit getrennten Tages- und Monatslimits (Tokens & Requests)
  • Token-Zählung via tiktoken (cl100k_base)
  • Usage-Tracking mit automatischem täglichem/monatlichem Reset
  • Web-Admin-Oberfläche für User- und Quota-Verwaltung
  • OpenAI-kompatibler /v1/chat/completions-Endpunkt

Sicherheit

  • Passwörter mit bcrypt gehasht
  • API-Keys als SHA-256-Hash in der DB Plaintext wird nur einmalig bei Erstellung zurückgegeben
  • Admin-Zugriff über is_admin-Flag in der DB, nicht über Hardcoded-Namen
  • CORS-Origins konfigurierbar via ALLOWED_ORIGINS
  • Quota-Check atomar mit SELECT FOR UPDATE (kein TOCTOU-Race)

Installation & Start

Voraussetzungen

  • Python 3.12+
  • PostgreSQL 16+ (oder SQLite für Entwicklung)
  • Node.js 18+ (für Frontend)

Lokal mit SQLite (Entwicklung)

# Backend
cd backend
pip install -r requirements.txt
python init_db.py
python setup_admin.py
uvicorn main:app --reload --port 8000

# Admin-API (in neuem Terminal)
uvicorn admin:app --reload --port 8001

# Frontend (in neuem Terminal)
cd frontend
npm install
npm run dev

Mit PostgreSQL & Docker (Produktion)

docker compose up -d
docker compose exec backend python init_db.py
docker compose exec backend python setup_admin.py

Konfiguration

.env-Datei im backend/-Verzeichnis anlegen:

DATABASE_URL=postgresql://user:pass@host:5432/db
OLLAMA_URL=http://ollama:11434
ALLOWED_ORIGINS=https://admin.example.com
Variable Standard Beschreibung
DATABASE_URL PostgreSQL lokal DB-Verbindungsstring; sqlite:/// für SQLite
OLLAMA_URL http://localhost:11434 Adresse der Ollama-Instanz
ALLOWED_ORIGINS http://localhost:5173 Kommagetrennte CORS-Origins für die Admin-UI

Proxy-Endpunkte

Alle Endpunkte erfordern einen gültigen API-Key im Authorization-Header.

curl -X POST http://localhost:8000/api/generate \
  -H "Authorization: Bearer sk-xxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"model":"llama3","prompt":"Say hello"}'
Endpunkt Beschreibung
POST /api/generate Ollama generate
POST /api/chat Ollama chat
GET /api/tags Verfügbare Modelle
GET /v1/models Modelle (OpenAI-Format)
POST /v1/chat/completions Chat (OpenAI-Format)

Admin-API (Port 8001)

Alle Endpunkte erfordern einen API-Key eines Nutzers mit is_admin=true.

Endpunkt Methode Beschreibung
/api/users GET Alle User auflisten
/api/users POST Neuen User anlegen
/api/api-keys GET Alle API-Keys auflisten
/api/api-keys POST Neuen API-Key erstellen (Plaintext einmalig in Response)
/api/api-keys/{id}/deactivate PUT API-Key deaktivieren
/api/quotas/{user_id} PUT Quota für User setzen

Quota setzen

curl -X PUT http://localhost:8001/api/quotas/1 \
  -H "Authorization: Bearer sk-admin-key" \
  -H "Content-Type: application/json" \
  -d '{
    "daily_tokens": 1000000,
    "monthly_tokens": 10000000,
    "daily_requests": 1000,
    "monthly_requests": 10000
  }'

null für ein Limit bedeutet unbegrenzt.

Tests

cd backend
python -m pytest tests/ -v

Projektstruktur

llm_quota/
├── backend/
│   ├── main.py           # Proxy-Server
│   ├── admin.py          # Admin-API
│   ├── database.py       # DB-Verbindung & Session
│   ├── models.py         # SQLAlchemy-Modelle
│   ├── schemas.py        # Pydantic-Schemas
│   ├── crud.py           # DB-Operationen & Token-Zählung
│   ├── init_db.py        # Tabellen anlegen
│   ├── setup_admin.py    # Admin-User & API-Key erstellen
│   ├── requirements.txt
│   ├── Dockerfile
│   └── tests/
│       ├── conftest.py   # Fixtures
│       ├── test_auth.py  # Authentifizierungs-Tests
│       └── test_quota.py # Quota- & Token-Tests
├── frontend/
│   └── src/
│       ├── main.jsx
│       └── styles.css
├── .gitignore
└── docker-compose.yml

Lizenz

MIT

Description
No description provided
Readme 206 KiB
Languages
Python 55.3%
JavaScript 28.4%
CSS 9.8%
Shell 4.9%
Dockerfile 1.1%
Other 0.5%