Implement API key usage
This commit is contained in:
parent
0be7a9d0d7
commit
976908642b
4 changed files with 50 additions and 4 deletions
|
|
@ -4,6 +4,7 @@
|
||||||
# Server connection settings
|
# Server connection settings
|
||||||
ORPHEUS_API_URL=http://127.0.0.1:1234/v1/completions
|
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_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
|
# Generation parameters
|
||||||
ORPHEUS_MAX_TOKENS=8192 # If you want longer completions, increase this value
|
ORPHEUS_MAX_TOKENS=8192 # If you want longer completions, increase this value
|
||||||
|
|
|
||||||
|
|
@ -140,6 +140,7 @@ The server provides an OpenAI-compatible API endpoint at `/v1/audio/speech`:
|
||||||
```bash
|
```bash
|
||||||
curl http://localhost:5005/v1/audio/speech \
|
curl http://localhost:5005/v1/audio/speech \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
|
-H "Authorization: Bearer your_api_key_here" \
|
||||||
-d '{
|
-d '{
|
||||||
"model": "orpheus",
|
"model": "orpheus",
|
||||||
"input": "Hello world! This is a test of the Orpheus TTS system.",
|
"input": "Hello world! This is a test of the Orpheus TTS system.",
|
||||||
|
|
@ -165,6 +166,7 @@ Additionally, a simpler `/speak` endpoint is available:
|
||||||
```bash
|
```bash
|
||||||
curl -X POST http://localhost:5005/speak \
|
curl -X POST http://localhost:5005/speak \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
|
-H "Authorization: Bearer your_api_key_here" \
|
||||||
-d '{
|
-d '{
|
||||||
"text": "Hello world! This is a test.",
|
"text": "Hello world! This is a test.",
|
||||||
"voice": "tara"
|
"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
|
2. In OpenWebUI, go to Admin Panel > Settings > Audio
|
||||||
3. Change TTS from Web API to OpenAI
|
3. Change TTS from Web API to OpenAI
|
||||||
4. Set APIBASE URL to your server address (e.g., `http://localhost:5005/v1`)
|
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`
|
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`
|
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_URL`: URL of the LLM inference API (tts_engine/inference.py)
|
||||||
- `ORPHEUS_API_TIMEOUT`: Timeout in seconds for API requests (default: 120)
|
- `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_MAX_TOKENS`: Maximum tokens to generate (default: 8192)
|
||||||
- `ORPHEUS_TEMPERATURE`: Temperature for generation (default: 0.6)
|
- `ORPHEUS_TEMPERATURE`: Temperature for generation (default: 0.6)
|
||||||
- `ORPHEUS_TOP_P`: Top-p sampling parameter (default: 0.9)
|
- `ORPHEUS_TOP_P`: Top-p sampling parameter (default: 0.9)
|
||||||
|
|
|
||||||
34
app.py
34
app.py
|
|
@ -7,6 +7,7 @@ import time
|
||||||
import asyncio
|
import asyncio
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import List, Optional
|
from typing import List, Optional
|
||||||
|
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
|
|
||||||
# Function to ensure .env file exists
|
# Function to ensure .env file exists
|
||||||
|
|
@ -28,7 +29,7 @@ ensure_env_file_exists()
|
||||||
# Load environment variables from .env file
|
# Load environment variables from .env file
|
||||||
load_dotenv(override=True)
|
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.responses import HTMLResponse, FileResponse, JSONResponse
|
||||||
from fastapi.staticfiles import StaticFiles
|
from fastapi.staticfiles import StaticFiles
|
||||||
from fastapi.templating import Jinja2Templates
|
from fastapi.templating import Jinja2Templates
|
||||||
|
|
@ -59,6 +60,33 @@ app.mount("/static", StaticFiles(directory="static"), name="static")
|
||||||
# Setup templates
|
# Setup templates
|
||||||
templates = Jinja2Templates(directory="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
|
# API models
|
||||||
class SpeechRequest(BaseModel):
|
class SpeechRequest(BaseModel):
|
||||||
input: str
|
input: str
|
||||||
|
|
@ -75,7 +103,7 @@ class APIResponse(BaseModel):
|
||||||
|
|
||||||
# OpenAI-compatible API endpoint
|
# OpenAI-compatible API endpoint
|
||||||
@app.post("/v1/audio/speech")
|
@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.
|
Generate speech from text using the Orpheus TTS model.
|
||||||
Compatible with OpenAI's /v1/audio/speech endpoint.
|
Compatible with OpenAI's /v1/audio/speech endpoint.
|
||||||
|
|
@ -116,7 +144,7 @@ async def create_speech_api(request: SpeechRequest):
|
||||||
|
|
||||||
# Legacy API endpoint for compatibility
|
# Legacy API endpoint for compatibility
|
||||||
@app.post("/speak")
|
@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"""
|
"""Legacy endpoint for compatibility with existing clients"""
|
||||||
data = await request.json()
|
data = await request.json()
|
||||||
text = data.get("text", "")
|
text = data.get("text", "")
|
||||||
|
|
|
||||||
|
|
@ -85,9 +85,17 @@ API_URL = os.environ.get("ORPHEUS_API_URL")
|
||||||
if not API_URL:
|
if not API_URL:
|
||||||
print("WARNING: ORPHEUS_API_URL not set. API calls will fail until configured.")
|
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 = {
|
HEADERS = {
|
||||||
"Content-Type": "application/json"
|
"Content-Type": "application/json"
|
||||||
}
|
}
|
||||||
|
if API_KEY:
|
||||||
|
HEADERS["Authorization"] = f"Bearer {API_KEY}"
|
||||||
|
|
||||||
# Request timeout settings
|
# Request timeout settings
|
||||||
try:
|
try:
|
||||||
|
|
@ -252,6 +260,12 @@ def generate_tokens_from_api(prompt: str, voice: str = DEFAULT_VOICE, temperatur
|
||||||
|
|
||||||
if response.status_code != 200:
|
if response.status_code != 200:
|
||||||
print(f"Error: API request failed with status code {response.status_code}")
|
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}")
|
print(f"Error details: {response.text}")
|
||||||
# Retry on server errors (5xx) but not on client errors (4xx)
|
# Retry on server errors (5xx) but not on client errors (4xx)
|
||||||
if response.status_code >= 500:
|
if response.status_code >= 500:
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue