Implement API key usage

This commit is contained in:
Jefferson Phillips 2025-04-02 14:49:52 -04:00
parent 0be7a9d0d7
commit 976908642b
4 changed files with 50 additions and 4 deletions

View file

@ -4,6 +4,7 @@
# Server connection settings
ORPHEUS_API_URL=http://127.0.0.1:1234/v1/completions
ORPHEUS_API_TIMEOUT=120 # You should scale this value based on max tokens and your inference speed
ORPHEUS_API_KEY=your_api_key_here # API key for authentication with the OpenAI-compatible API
# Generation parameters
ORPHEUS_MAX_TOKENS=8192 # If you want longer completions, increase this value

View file

@ -140,6 +140,7 @@ The server provides an OpenAI-compatible API endpoint at `/v1/audio/speech`:
```bash
curl http://localhost:5005/v1/audio/speech \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your_api_key_here" \
-d '{
"model": "orpheus",
"input": "Hello world! This is a test of the Orpheus TTS system.",
@ -165,6 +166,7 @@ Additionally, a simpler `/speak` endpoint is available:
```bash
curl -X POST http://localhost:5005/speak \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your_api_key_here" \
-d '{
"text": "Hello world! This is a test.",
"voice": "tara"
@ -265,7 +267,7 @@ You can easily integrate this TTS solution with [OpenWebUI](https://github.com/o
2. In OpenWebUI, go to Admin Panel > Settings > Audio
3. Change TTS from Web API to OpenAI
4. Set APIBASE URL to your server address (e.g., `http://localhost:5005/v1`)
5. API Key can be set to "not-needed"
5. Set API Key to your configured API key or "not-needed" if API key authentication is not enabled
6. Set TTS Voice to one of the available voices: `tara`, `leah`, `jess`, `leo`, `dan`, `mia`, `zac`, or `zoe`
7. Set TTS Model to `tts-1`
@ -295,6 +297,7 @@ You can configure the system using environment variables or a `.env` file:
- `ORPHEUS_API_URL`: URL of the LLM inference API (tts_engine/inference.py)
- `ORPHEUS_API_TIMEOUT`: Timeout in seconds for API requests (default: 120)
- `ORPHEUS_API_KEY`: API key for authentication with the OpenAI-compatible API (optional)
- `ORPHEUS_MAX_TOKENS`: Maximum tokens to generate (default: 8192)
- `ORPHEUS_TEMPERATURE`: Temperature for generation (default: 0.6)
- `ORPHEUS_TOP_P`: Top-p sampling parameter (default: 0.9)

34
app.py
View file

@ -7,6 +7,7 @@ import time
import asyncio
from datetime import datetime
from typing import List, Optional
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from dotenv import load_dotenv
# Function to ensure .env file exists
@ -28,7 +29,7 @@ ensure_env_file_exists()
# Load environment variables from .env file
load_dotenv(override=True)
from fastapi import FastAPI, Request, Form, HTTPException, Depends
from fastapi import FastAPI, Request, Form, HTTPException, Depends, Security
from fastapi.responses import HTMLResponse, FileResponse, JSONResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
@ -59,6 +60,33 @@ app.mount("/static", StaticFiles(directory="static"), name="static")
# Setup templates
templates = Jinja2Templates(directory="templates")
# API key authentication
security = HTTPBearer(auto_error=False)
# Get API key from environment
API_KEY = os.environ.get("ORPHEUS_API_KEY")
# Function to verify API key
async def verify_api_key(credentials: HTTPAuthorizationCredentials = Security(security)):
"""
Verify the API key from the Authorization header.
If no API key is configured, authentication is skipped.
"""
# If no API key is configured, skip authentication
if not API_KEY:
return True
# If API key is configured but no credentials provided, raise 401
if not credentials:
raise HTTPException(
status_code=401,
detail="Missing API key. Please provide an API key in the Authorization header."
)
# Verify the API key
if credentials.credentials != API_KEY:
raise HTTPException(status_code=401, detail="Invalid API key")
# API models
class SpeechRequest(BaseModel):
input: str
@ -75,7 +103,7 @@ class APIResponse(BaseModel):
# OpenAI-compatible API endpoint
@app.post("/v1/audio/speech")
async def create_speech_api(request: SpeechRequest):
async def create_speech_api(request: SpeechRequest, authorized: bool = Depends(verify_api_key)):
"""
Generate speech from text using the Orpheus TTS model.
Compatible with OpenAI's /v1/audio/speech endpoint.
@ -116,7 +144,7 @@ async def create_speech_api(request: SpeechRequest):
# Legacy API endpoint for compatibility
@app.post("/speak")
async def speak(request: Request):
async def speak(request: Request, authorized: bool = Depends(verify_api_key)):
"""Legacy endpoint for compatibility with existing clients"""
data = await request.json()
text = data.get("text", "")

View file

@ -85,9 +85,17 @@ API_URL = os.environ.get("ORPHEUS_API_URL")
if not API_URL:
print("WARNING: ORPHEUS_API_URL not set. API calls will fail until configured.")
# Get API key from environment
API_KEY = os.environ.get("ORPHEUS_API_KEY")
if not API_KEY:
print("WARNING: ORPHEUS_API_KEY not set. API calls may fail if the endpoint requires authentication.")
# Set up headers with authentication if API key is provided
HEADERS = {
"Content-Type": "application/json"
}
if API_KEY:
HEADERS["Authorization"] = f"Bearer {API_KEY}"
# Request timeout settings
try:
@ -252,6 +260,12 @@ def generate_tokens_from_api(prompt: str, voice: str = DEFAULT_VOICE, temperatur
if response.status_code != 200:
print(f"Error: API request failed with status code {response.status_code}")
if response.status_code == 401:
print(f"Authentication failed. Please check your API key in the .env file.")
return
elif response.status_code == 403:
print(f"Authorization failed. Your API key may not have access to this resource.")
return
print(f"Error details: {response.text}")
# Retry on server errors (5xx) but not on client errors (4xx)
if response.status_code >= 500: