| --- |
| title: APIarium |
| emoji: π |
| colorFrom: blue |
| colorTo: green |
| sdk: docker |
| app_port: 1111 |
| --- |
| |
| # π APIarium |
|
|
| OpenAI-compatible LLM API gateway with multi-provider routing, encrypted configuration, and admin management. |
|
|
| ## Features |
|
|
| - **Multi-Model Routing** β Route requests to multiple LLM providers through a unified OpenAI-compatible API |
| - **Encrypted Config** β Sensitive values (API keys, tokens) stored as AES-256-GCM encrypted blobs in the repo |
| - **Admin Dashboard** β Web UI for managing API keys, providers, and balance monitoring |
| - **Cloudflare Turnstile** β Bot protection for admin endpoints |
| - **VPN Detection** β Free VPN/proxy detection via proxycheck.io |
| - **IP Blocking** β Built-in IP blocklist support |
| - **GitHub Gist Storage** β API key persistence via encrypted GitHub Gists |
| - **HuggingFace Dataset Logging** β Request/response logging to HF Datasets |
| - **Dynamic Providers** β Add/remove upstream providers at runtime |
|
|
| ## Architecture |
|
|
| ``` |
| Client β APIarium (FastAPI) β Multiple LLM Upstreams |
| β |
| Admin Panel (Turnstile protected) |
| β |
| GitHub Gist (encrypted key storage) |
| HF Dataset (request logging) |
| ``` |
|
|
| ## Supported Models |
|
|
| Models are exposed as aliases through the `/v1/models` endpoint. Each alias routes to one or more upstream providers configured in `app/config.py`. |
|
|
| ## API Endpoints |
|
|
| ### Proxy |
|
|
| | Method | Endpoint | Description | |
| |--------|----------|-------------| |
| | `POST` | `/v1/chat/completions` | OpenAI-compatible chat completion | |
| | `POST` | `/v1/completions` | Text completions | |
| | `GET` | `/v1/models` | List available models | |
|
|
| ### Admin |
|
|
| | Method | Endpoint | Description | |
| |--------|----------|-------------| |
| | `GET` | `/admin` | Admin dashboard (Turnstile protected) | |
| | `GET` | `/admin/keys` | API key management | |
| | `GET` | `/admin/providers` | Provider management | |
| | `GET` | `/admin/balance` | Balance monitoring | |
| | `POST` | `/admin/verify-turnstile` | Turnstile token verification | |
|
|
| ### Health |
|
|
| | Method | Endpoint | Description | |
| |--------|----------|-------------| |
| | `GET` | `/health` | Health check | |
|
|
| ## Environment Variables |
|
|
| | Variable | Required | Description | |
| |----------|----------|-------------| |
| | `AES_KEY` | β
Yes | Base64-encoded 32-byte AES-256 key for decrypting config secrets | |
| | `HF_TOKEN` | Optional | HuggingFace token for dataset logging | |
| | `TURNSTILE_SITE_KEY` | Optional | Cloudflare Turnstile site key for admin protection | |
| | `TURNSTILE_SECRET_KEY` | Optional | Cloudflare Turnstile secret key for server-side verification | |
| | `UPSTREAM_API_KEY` | Optional | Fallback API key for upstreams without specific keys | |
|
|
| ## Configuration |
|
|
| ### Encrypted Secrets |
|
|
| Sensitive values are encrypted using AES-256-GCM and stored in `app/config.py`: |
|
|
| ```bash |
| # Encrypt a value locally |
| python encrypt_config.py "your-secret-value" |
| # Output: enc:v1:nonce:ciphertext |
| ``` |
|
|
| In code: |
|
|
| ```python |
| GITHUB_TOKEN = _decrypt("enc:v1:...") |
| ``` |
|
|
| The `AES_KEY` environment variable must be set at runtime for decryption. |
|
|
| ### Generating an AES Key |
|
|
| ```python |
| import base64, os |
| key = base64.b64encode(os.urandom(32)).decode() |
| print(key) |
| ``` |
|
|
| Store this value as the `AES_KEY` secret in your deployment environment. |
|
|
| ### Upstream Routing |
|
|
| Models are mapped to upstream endpoints in the `UPSTREAMS` dict inside `app/config.py`: |
|
|
| ```python |
| UPSTREAMS = { |
| "model-alias": [ |
| {"url": "https://upstream.example.com/v1", "model": "real-model-name"}, |
| ], |
| } |
| ``` |
|
|
| ### Per-Upstream API Keys |
|
|
| ```python |
| UPSTREAM_API_KEYS = { |
| "https://upstream-a.example.com/v1": "sk-...", |
| "https://upstream-b.example.com/v1": "sk-...", |
| } |
| ``` |
|
|
| If no key is configured for a URL, the `UPSTREAM_API_KEY` env var is used as fallback. |
|
|
| ### Balance Endpoints |
|
|
| Provider balance checking via `BALANCE_ENDPOINTS`: |
|
|
| ```python |
| BALANCE_ENDPOINTS = { |
| "provider-name": "https://api.provider.com/v1/balance", |
| } |
| ``` |
|
|
| ## Local Development |
|
|
| ```bash |
| # Clone |
| git clone https://huggingface.co/spaces/rnilkyway/APIarium |
| cd APIarium |
| |
| # Create virtual environment |
| python -m venv venv |
| source venv/bin/activate # Windows: venv\Scripts\activate |
| |
| # Install dependencies |
| pip install -r requirements.txt |
| |
| # Set required env vars |
| export AES_KEY="your-base64-encoded-32-byte-key" |
| |
| # Run |
| uvicorn app.index:app --host 0.0.0.0 --port 1111 --reload |
| ``` |
|
|
| ## Docker |
|
|
| ```bash |
| docker build -t apiarium . |
| docker run -p 1111:1111 -e AES_KEY="your-key" apiarium |
| ``` |
|
|
| ## Deployment on HuggingFace Spaces |
|
|
| This space runs on **HuggingFace Spaces** using the Docker SDK (`app_port: 1111`). |
|
|
| ### Setting Secrets |
|
|
| 1. Go to **Space Settings β Variables and secrets** |
| 2. Add `AES_KEY` with your base64-encoded 32-byte key |
| 3. Optionally add `TURNSTILE_SITE_KEY` and `TURNSTILE_SECRET_KEY` |
| 4. Optionally add `HF_TOKEN` for dataset logging |
|
|
| ### Triggering a Rebuild |
|
|
| Any commit to the `main` branch automatically triggers a rebuild. |
|
|
| ## Project Structure |
|
|
| ``` |
| APIarium/ |
| βββ app/ |
| β βββ index.py # Main FastAPI application |
| β βββ config.py # Configuration & encrypted secrets |
| β βββ templates.py # HTML templates for admin UI |
| βββ encrypt_config.py # AES encryption utility |
| βββ test_gist.py # Gist storage integration tests |
| βββ Dockerfile # Container definition |
| βββ requirements.txt # Python dependencies |
| βββ README.md # This file |
| ``` |
|
|
| ## Security |
|
|
| - All sensitive config values are AES-256-GCM encrypted at rest |
| - Master key authentication for admin access |
| - Cloudflare Turnstile bot protection on admin endpoints |
| - Free VPN/proxy detection and automatic blocking |
| - IP blocklist support |
| - CORS configured for allowed origins |
| - Encrypted GitHub Gist storage for API key persistence |
|
|