Fix: API Key validation from database, Python 3.12 compatibility, persistent volumes

This commit is contained in:
Dominic Ballenthin
2026-01-29 01:25:11 +01:00
parent 008ef63bfd
commit c5ecd2ee76
5 changed files with 76 additions and 24 deletions

View File

@@ -19,11 +19,11 @@ services:
- ADMIN_USER=${ADMIN_USER:-admin} - ADMIN_USER=${ADMIN_USER:-admin}
- ADMIN_PASSWORD=${ADMIN_PASSWORD:--whisper12510-} - ADMIN_PASSWORD=${ADMIN_PASSWORD:--whisper12510-}
- LOG_RETENTION_DAYS=${LOG_RETENTION_DAYS:-30} - LOG_RETENTION_DAYS=${LOG_RETENTION_DAYS:-30}
- DATABASE_URL=sqlite:///app/data/whisper_api.db - DATABASE_URL=sqlite:////app/data/whisper_api.db
volumes: volumes:
- ./models:/app/models - whisper_models:/app/models
- ./data:/app/data - whisper_data:/app/data
- ./uploads:/app/uploads - whisper_uploads:/app/uploads
deploy: deploy:
resources: resources:
reservations: reservations:
@@ -37,3 +37,8 @@ services:
timeout: 10s timeout: 10s
retries: 3 retries: 3
start_period: 60s start_period: 60s
volumes:
whisper_models:
whisper_data:
whisper_uploads:

View File

@@ -3,18 +3,33 @@ FROM nvidia/cuda:12.1.0-runtime-ubuntu22.04
# Prevent interactive prompts # Prevent interactive prompts
ENV DEBIAN_FRONTEND=noninteractive ENV DEBIAN_FRONTEND=noninteractive
# Install system dependencies # Install system dependencies with Python 3.12 from deadsnakes PPA
RUN apt-get update && apt-get install -y \ RUN apt-get update && apt-get install -y \
python3.11 \ software-properties-common \
python3.11-pip \ pkg-config \
python3.11-venv \ && add-apt-repository ppa:deadsnakes/ppa -y \
&& apt-get update \
&& apt-get install -y \
python3.12 \
python3.12-dev \
python3.12-venv \
ffmpeg \ ffmpeg \
libavformat-dev \
libavcodec-dev \
libavdevice-dev \
libavutil-dev \
libavfilter-dev \
libswscale-dev \
libswresample-dev \
curl \ curl \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*
# Set Python 3.11 as default # Install pip for Python 3.12
RUN update-alternatives --install /usr/bin/python python /usr/bin/python3.11 1 RUN curl -sS https://bootstrap.pypa.io/get-pip.py | python3.12
RUN update-alternatives --install /usr/bin/pip pip /usr/bin/pip3 1
# Set Python 3.12 as default
RUN update-alternatives --install /usr/bin/python python /usr/bin/python3.12 1
RUN update-alternatives --install /usr/bin/pip pip /usr/local/bin/pip3 1
# Set working directory # Set working directory
WORKDIR /app WORKDIR /app
@@ -23,12 +38,19 @@ WORKDIR /app
COPY requirements.txt . COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt RUN pip install --no-cache-dir -r requirements.txt
# Copy entrypoint script
COPY docker/entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
# Create necessary directories # Create necessary directories
RUN mkdir -p /app/models /app/data /app/uploads RUN mkdir -p /app/models /app/data /app/uploads
# Copy application code # Copy application code
COPY src/ ./src/ COPY src/ ./src/
# Set entrypoint
ENTRYPOINT ["/entrypoint.sh"]
# Set environment variables # Set environment variables
ENV PYTHONPATH=/app ENV PYTHONPATH=/app
ENV PYTHONUNBUFFERED=1 ENV PYTHONUNBUFFERED=1

9
docker/entrypoint.sh Normal file
View File

@@ -0,0 +1,9 @@
#!/bin/bash
set -e
# Create directories if they don't exist and set permissions
mkdir -p /app/data /app/uploads /app/models
chmod 777 /app/data /app/uploads /app/models
# Start the application
exec "$@"

View File

@@ -6,17 +6,17 @@ jinja2==3.1.3
aiofiles==23.2.1 aiofiles==23.2.1
# Whisper # Whisper
openai-whisper==20231117 openai-whisper==20240930
faster-whisper==0.10.0 faster-whisper==1.1.0
torch==2.1.2 torch==2.5.1
torchaudio==2.1.2 torchaudio==2.5.1
# Database # Database
sqlalchemy==2.0.25 sqlalchemy==2.0.36
alembic==1.13.1 alembic==1.14.0
# Audio processing # Audio processing
librosa==0.10.1 librosa==0.10.2.post1
soundfile==0.12.1 soundfile==0.12.1
# Utilities # Utilities

View File

@@ -14,6 +14,10 @@ from sqlalchemy.orm import Session
router = APIRouter() router = APIRouter()
from src.services.stats_service import hash_api_key
from src.database.db import SessionLocal
from src.database.models import ApiKey
def verify_api_key(authorization: Optional[str] = Header(None)): def verify_api_key(authorization: Optional[str] = Header(None)):
"""Verify API key from Authorization header""" """Verify API key from Authorization header"""
if not authorization: if not authorization:
@@ -24,16 +28,28 @@ def verify_api_key(authorization: Optional[str] = Header(None)):
raise HTTPException(status_code=401, detail="Invalid authorization format") raise HTTPException(status_code=401, detail="Invalid authorization format")
api_key = authorization.replace("Bearer ", "").strip() api_key = authorization.replace("Bearer ", "").strip()
# Check environment variable keys first
valid_keys = settings.get_api_keys_list() valid_keys = settings.get_api_keys_list()
if api_key in valid_keys:
if not valid_keys:
raise HTTPException(status_code=500, detail="No API keys configured")
if api_key not in valid_keys:
raise HTTPException(status_code=401, detail="Invalid API key")
return api_key return api_key
# Check database keys
db = SessionLocal()
try:
key_hash = hash_api_key(api_key)
db_key = db.query(ApiKey).filter(
ApiKey.key_hash == key_hash,
ApiKey.is_active == True
).first()
if db_key:
return api_key
finally:
db.close()
raise HTTPException(status_code=401, detail="Invalid API key")
@router.get("/models") @router.get("/models")
async def list_models(api_key: str = Depends(verify_api_key)): async def list_models(api_key: str = Depends(verify_api_key)):