mirror of
https://github.com/Routstr/routstr-core.git
synced 2026-07-30 15:26:14 +00:00
Merge pull request #160 from Routstr/azure-openai-compatibility
Azure OpenAI compatibility
This commit is contained in:
@@ -10,7 +10,6 @@ Routstr Core is configured through environment variables. This guide covers all
|
||||
|----------|-------------|---------|----------|
|
||||
| `UPSTREAM_BASE_URL` | Base URL of the OpenAI-compatible API to proxy | - | ✅ |
|
||||
| `UPSTREAM_API_KEY` | API key for the upstream service | - | ❌ |
|
||||
| `DATABASE_URL` | SQLite database connection string | `sqlite+aiosqlite:///keys.db` | ❌ |
|
||||
| `ADMIN_PASSWORD` | Password for admin dashboard access | - | ⚠️ |
|
||||
|
||||
### Node Information
|
||||
@@ -55,13 +54,12 @@ Routstr Core is configured through environment variables. This guide covers all
|
||||
| `LOG_LEVEL` | Logging level (DEBUG, INFO, WARNING, ERROR) | `INFO` | ❌ |
|
||||
| `ENABLE_CONSOLE_LOGGING` | Enable console log output | `true` | ❌ |
|
||||
|
||||
### Model Management
|
||||
### Other
|
||||
|
||||
| Variable | Description | Default | Required |
|
||||
|----------|-------------|---------|----------|
|
||||
| `MODELS_PATH` | Path to custom models.json file | `models.json` | ❌ |
|
||||
| `BASE_URL` | Base URL for fetching model info | `https://openrouter.ai/api/v1` | ❌ |
|
||||
| `SOURCE` | Filter models by source provider | - | ❌ |
|
||||
| `CHAT_COMPLETIONS_API_VERSION` | Append `api-version` to `/chat/completions` (Azure OpenAI) | - | ❌ |
|
||||
| `DATABASE_URL` | SQLite database connection string | `sqlite+aiosqlite:///keys.db` | ❌ |
|
||||
|
||||
## Configuration Examples
|
||||
|
||||
@@ -84,6 +82,15 @@ MODEL_BASED_PRICING=true
|
||||
MODELS_PATH=/app/config/anthropic-models.json
|
||||
```
|
||||
|
||||
### Azure OpenAI (optional)
|
||||
|
||||
```bash
|
||||
# .env
|
||||
UPSTREAM_BASE_URL=https://<resource>.openai.azure.com/openai/deployments/<deployment>
|
||||
UPSTREAM_API_KEY=<azure_api_key>
|
||||
CHAT_COMPLETIONS_API_VERSION=2024-05-01-preview
|
||||
```
|
||||
|
||||
### High-Security Setup
|
||||
|
||||
```bash
|
||||
@@ -174,6 +181,7 @@ Create a `models.json` file:
|
||||
### Admin Password
|
||||
|
||||
Generate a strong password:
|
||||
|
||||
```bash
|
||||
openssl rand -base64 32
|
||||
```
|
||||
@@ -211,18 +219,21 @@ curl http://localhost:8000/v1/info
|
||||
### Common Issues
|
||||
|
||||
**Missing Upstream URL**
|
||||
|
||||
```
|
||||
ERROR: UPSTREAM_BASE_URL not set
|
||||
Solution: Set UPSTREAM_BASE_URL in .env
|
||||
```
|
||||
|
||||
**Invalid Cashu Mint**
|
||||
|
||||
```
|
||||
ERROR: Failed to connect to mint
|
||||
Solution: Verify CASHU_MINTS URLs are accessible
|
||||
```
|
||||
|
||||
**Database Errors**
|
||||
|
||||
```
|
||||
ERROR: Database connection failed
|
||||
Solution: Check DATABASE_URL and file permissions
|
||||
@@ -233,6 +244,7 @@ Solution: Check DATABASE_URL and file permissions
|
||||
### Multiple Mints
|
||||
|
||||
Configure fallback mints:
|
||||
|
||||
```bash
|
||||
CASHU_MINTS=https://primary.mint,https://backup1.mint,https://backup2.mint
|
||||
```
|
||||
@@ -240,6 +252,7 @@ CASHU_MINTS=https://primary.mint,https://backup1.mint,https://backup2.mint
|
||||
### Custom Database
|
||||
|
||||
Use PostgreSQL instead of SQLite:
|
||||
|
||||
```bash
|
||||
DATABASE_URL=postgresql+asyncpg://user:pass@localhost/routstr
|
||||
```
|
||||
@@ -247,6 +260,7 @@ DATABASE_URL=postgresql+asyncpg://user:pass@localhost/routstr
|
||||
### Proxy Settings
|
||||
|
||||
For corporate environments:
|
||||
|
||||
```bash
|
||||
HTTP_PROXY=http://proxy.company.com:8080
|
||||
HTTPS_PROXY=http://proxy.company.com:8080
|
||||
@@ -256,4 +270,4 @@ HTTPS_PROXY=http://proxy.company.com:8080
|
||||
|
||||
- [User Guide](../user-guide/introduction.md) - Start using Routstr
|
||||
- [Admin Dashboard](../user-guide/admin-dashboard.md) - Manage your node
|
||||
- [Custom Pricing](../advanced/custom-pricing.md) - Advanced pricing strategies
|
||||
- [Custom Pricing](../advanced/custom-pricing.md) - Advanced pricing strategies
|
||||
|
||||
@@ -316,6 +316,15 @@ client = OpenAI(
|
||||
)
|
||||
```
|
||||
|
||||
### Azure OpenAI compatibility
|
||||
|
||||
To use Azure OpenAI through Routstr with minimal changes:
|
||||
|
||||
- Set `UPSTREAM_BASE_URL` to your Azure deployments URL, for example: `https://<resource>.openai.azure.com/openai/deployments/<deployment>`
|
||||
- Set `CHAT_COMPLETIONS_API_VERSION=2024-05-01-preview`
|
||||
|
||||
When this env var is set, Routstr automatically appends `api-version=2024-05-01-preview` to all upstream `/chat/completions` requests.
|
||||
|
||||
### Async Operations
|
||||
|
||||
For high-performance applications:
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import json
|
||||
import os
|
||||
from typing import Mapping
|
||||
|
||||
from fastapi import HTTPException, Response
|
||||
from fastapi.requests import Request
|
||||
@@ -14,6 +15,7 @@ logger = get_logger(__name__)
|
||||
|
||||
UPSTREAM_BASE_URL = os.environ.get("UPSTREAM_BASE_URL", "")
|
||||
UPSTREAM_API_KEY = os.environ.get("UPSTREAM_API_KEY", "")
|
||||
CHAT_COMPLETIONS_API_VERSION = os.environ.get("CHAT_COMPLETIONS_API_VERSION", "")
|
||||
|
||||
if not UPSTREAM_BASE_URL:
|
||||
raise ValueError("Please set the UPSTREAM_BASE_URL environment variable")
|
||||
@@ -201,3 +203,13 @@ def prepare_upstream_headers(request_headers: dict) -> dict:
|
||||
)
|
||||
|
||||
return headers
|
||||
|
||||
|
||||
def prepare_upstream_params(
|
||||
path: str, query_params: Mapping[str, str] | None
|
||||
) -> dict[str, str]:
|
||||
"""Prepare query params for upstream request, optionally adding api-version for chat/completions."""
|
||||
params: dict[str, str] = dict(query_params or {})
|
||||
if path.endswith("chat/completions") and CHAT_COMPLETIONS_API_VERSION:
|
||||
params["api-version"] = CHAT_COMPLETIONS_API_VERSION
|
||||
return params
|
||||
|
||||
@@ -9,7 +9,12 @@ from fastapi.responses import Response, StreamingResponse
|
||||
from ..core import get_logger
|
||||
from ..wallet import recieve_token, send_token
|
||||
from .cost_caculation import CostData, CostDataError, MaxCostData, calculate_cost
|
||||
from .helpers import UPSTREAM_BASE_URL, create_error_response, prepare_upstream_headers
|
||||
from .helpers import (
|
||||
UPSTREAM_BASE_URL,
|
||||
create_error_response,
|
||||
prepare_upstream_headers,
|
||||
prepare_upstream_params,
|
||||
)
|
||||
|
||||
logger = get_logger(__name__)
|
||||
|
||||
@@ -128,7 +133,7 @@ async def forward_to_upstream(
|
||||
url,
|
||||
headers=headers,
|
||||
content=request.stream(),
|
||||
params=request.query_params,
|
||||
params=prepare_upstream_params(path, request.query_params),
|
||||
),
|
||||
stream=True,
|
||||
)
|
||||
|
||||
+4
-3
@@ -21,6 +21,7 @@ from .payment.helpers import (
|
||||
create_error_response,
|
||||
get_max_cost_for_model,
|
||||
prepare_upstream_headers,
|
||||
prepare_upstream_params,
|
||||
)
|
||||
from .payment.x_cashu import x_cashu_handler
|
||||
|
||||
@@ -334,7 +335,7 @@ async def forward_to_upstream(
|
||||
url,
|
||||
headers=headers,
|
||||
content=request_body,
|
||||
params=request.query_params,
|
||||
params=prepare_upstream_params(path, request.query_params),
|
||||
),
|
||||
stream=True,
|
||||
)
|
||||
@@ -345,7 +346,7 @@ async def forward_to_upstream(
|
||||
url,
|
||||
headers=headers,
|
||||
content=request.stream(),
|
||||
params=request.query_params,
|
||||
params=prepare_upstream_params(path, request.query_params),
|
||||
),
|
||||
stream=True,
|
||||
)
|
||||
@@ -773,7 +774,7 @@ async def forward_get_to_upstream(
|
||||
url,
|
||||
headers=headers,
|
||||
content=request.stream(),
|
||||
params=request.query_params,
|
||||
params=prepare_upstream_params(path, request.query_params),
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user