Implement backend API foundation

- Created FastAPI application with CORS middleware
- Defined Pydantic models (RoleDetectionRequest, RolesResponse, TTSRequest, ErrorResponse)
- Implemented /api/health endpoint
- Set up error handling middleware for validation and general exceptions
- Configured logging with INFO level
- Added test script to verify API functionality
- Validates Requirements: 9.1, 9.2, 9.4
This commit is contained in:
2025-12-09 00:57:46 +00:00
parent f4bc759007
commit 31da896e56
3 changed files with 107 additions and 4 deletions

View File

@@ -1,6 +1,6 @@
# Implementation Plan # Implementation Plan
- [-] 1. Set up project structure and dependencies - [x] 1. Set up project structure and dependencies
- Create backend directory with FastAPI project structure - Create backend directory with FastAPI project structure
- Create frontend directory with React + TypeScript + Vite - Create frontend directory with React + TypeScript + Vite
- Configure Python virtual environment and install dependencies (fastapi, uvicorn, kokoro, soundfile, python-multipart) - Configure Python virtual environment and install dependencies (fastapi, uvicorn, kokoro, soundfile, python-multipart)
@@ -9,7 +9,7 @@
- Set up environment variable configuration for both projects - Set up environment variable configuration for both projects
- _Requirements: 9.6, 10.2, 11.1_ - _Requirements: 9.6, 10.2, 11.1_
- [ ] 2. Implement backend API foundation - [x] 2. Implement backend API foundation
- Create FastAPI application with CORS middleware - Create FastAPI application with CORS middleware
- Define Pydantic models for requests and responses (RoleDetectionRequest, RolesResponse, TTSRequest, ErrorResponse) - Define Pydantic models for requests and responses (RoleDetectionRequest, RolesResponse, TTSRequest, ErrorResponse)
- Implement /api/health endpoint - Implement /api/health endpoint

View File

@@ -1,10 +1,59 @@
""" """
FastAPI backend for Text to Audiobook application. FastAPI backend for Text to Audiobook application.
""" """
from fastapi import FastAPI import logging
from typing import List, Optional
from fastapi import FastAPI, Request, status
from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import JSONResponse
from fastapi.exceptions import RequestValidationError
from pydantic import BaseModel, Field
app = FastAPI(title="Text to Audiobook API") # Configure logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
# Pydantic Models
class RoleDetectionRequest(BaseModel):
"""Request model for role detection endpoint."""
text: str = Field(..., description="Text to analyze for role detection")
class RoleInfo(BaseModel):
"""Model representing a detected role."""
id: str = Field(..., description="Unique identifier for the role")
label: str = Field(..., description="Display name for the role")
class RolesResponse(BaseModel):
"""Response model for role detection endpoint."""
roles: List[RoleInfo] = Field(..., description="List of detected roles")
class RoleVoiceMapping(BaseModel):
"""Model for role-to-voice mapping."""
id: str = Field(..., description="Role identifier")
voice: str = Field(..., description="Kokoro voice ID")
class TTSRequest(BaseModel):
"""Request model for TTS generation endpoint."""
text: str = Field(..., description="Text to convert to speech")
lang: str = Field(..., description="Language code (a, b, f, j)")
roles: List[RoleVoiceMapping] = Field(..., description="Role to voice mappings")
speed: Optional[float] = Field(1.0, description="Playback speed (0.5-1.5)")
class ErrorResponse(BaseModel):
"""Standard error response model."""
error: str = Field(..., description="Error type")
message: str = Field(..., description="Human-readable error message")
details: Optional[dict] = Field(None, description="Additional error details")
# Initialize FastAPI app
app = FastAPI(
title="Text to Audiobook API",
description="API for converting text to multi-voice audiobooks using Kokoro TTS",
version="1.0.0"
)
# Configure CORS # Configure CORS
app.add_middleware( app.add_middleware(
@@ -15,8 +64,36 @@ app.add_middleware(
allow_headers=["*"], allow_headers=["*"],
) )
# Error handling middleware
@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request: Request, exc: RequestValidationError):
"""Handle validation errors with custom error response."""
logger.error(f"Validation error: {exc.errors()}")
return JSONResponse(
status_code=status.HTTP_400_BAD_REQUEST,
content={
"error": "ValidationError",
"message": "Invalid request data",
"details": {"errors": exc.errors()}
}
)
@app.exception_handler(Exception)
async def general_exception_handler(request: Request, exc: Exception):
"""Handle general exceptions with custom error response."""
logger.error(f"Unhandled exception: {str(exc)}", exc_info=True)
return JSONResponse(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
content={
"error": "InternalServerError",
"message": "An unexpected error occurred",
"details": {"error": str(exc)}
}
)
# API Endpoints
@app.get("/api/health") @app.get("/api/health")
async def health_check(): async def health_check():
"""Health check endpoint.""" """Health check endpoint."""
logger.info("Health check requested")
return {"status": "ok"} return {"status": "ok"}

26
backend/test_api.py Normal file
View File

@@ -0,0 +1,26 @@
#!/usr/bin/env python3
"""Simple test script for API foundation."""
import urllib.request
import json
def test_health():
"""Test health endpoint."""
response = urllib.request.urlopen('http://localhost:8001/api/health')
data = json.loads(response.read().decode())
print(f"✓ Health check: {data}")
def test_cors():
"""Test CORS headers."""
req = urllib.request.Request('http://localhost:8001/api/health',
headers={'Origin': 'http://localhost:5173'})
response = urllib.request.urlopen(req)
cors_origin = response.headers.get('Access-Control-Allow-Origin')
cors_creds = response.headers.get('Access-Control-Allow-Credentials')
print(f"✓ CORS Origin: {cors_origin}")
print(f"✓ CORS Credentials: {cors_creds}")
if __name__ == '__main__':
print("Testing API Foundation...")
test_health()
test_cors()
print("\nAll tests passed!")