TTS / app /api /routes.py
github-actions[bot]
Auto-deploy from GitHub: 6cd5884f5f59c8acb069f7a2a8f8ce8558f018b5
6203f3a
Raw
History Blame Contribute Delete
4.2 kB
from fastapi import APIRouter, UploadFile, File, Form, HTTPException
from fastapi.responses import FileResponse, JSONResponse
import os
import uuid
import aiofiles
from app.core.config import settings
from custom_logger import logger_config as logger
from app.db import crud
from app.services.worker import start_worker, is_worker_running
router = APIRouter()
@router.get("/")
async def index():
return FileResponse('index.html')
@router.post("/api/tasks/upload")
async def create_task(
text: str = Form(None),
file: UploadFile = File(None),
voice: str = Form("4"),
speed: float = Form(1.0),
hide_from_ui: str = Form("")
):
task_text = ""
if text:
task_text = text
elif file:
try:
content = await file.read()
task_text = content.decode('utf-8')
except Exception as e:
logger.error(f"Error reading uploaded file: {e}")
raise HTTPException(status_code=400, detail="Could not read file content")
if not task_text.strip():
raise HTTPException(status_code=400, detail="No text provided")
task_id = str(uuid.uuid4())
filename = file.filename if file else f"{task_text[:20]}..."
hide_from_ui_val = 1 if hide_from_ui.lower() in ['true', '1'] else 0
await crud.insert_task(task_id, filename, task_text, voice, speed, 'not_started', hide_from_ui_val)
await start_worker()
return JSONResponse(status_code=201, content={
'id': task_id,
'filename': filename,
'status': 'not_started',
'message': 'Task created successfully'
})
@router.get("/api/tasks")
async def get_tasks():
rows, queue_ids, processing_count, avg_time = await crud.get_all_tasks()
tasks = []
for row in rows:
queue_position = None
estimated_start_seconds = None
if row['status'] == 'not_started' and row['id'] in queue_ids:
queue_position = queue_ids.index(row['id']) + 1
tasks_ahead = queue_position - 1 + processing_count
estimated_start_seconds = round(tasks_ahead * avg_time)
tasks.append({
'id': row['id'],
'filename': row['filename'],
'status': row['status'],
'result': "HIDDEN_IN_LIST_VIEW",
'created_at': row['created_at'],
'processed_at': row['processed_at'],
'progress': row['progress'] or 0,
'progress_text': row['progress_text'],
'queue_position': queue_position,
'estimated_start_seconds': estimated_start_seconds
})
return tasks
@router.get("/api/tasks/{task_id}")
async def get_task(task_id: str):
result = await crud.get_task_by_id(task_id)
if not result:
raise HTTPException(status_code=404, detail="Task not found")
row, queue_position, estimated_start_seconds = result
return {
'id': row['id'],
'filename': row['filename'],
'text': row['text'],
'status': row['status'],
'result': row['text'], # result maps to text for detail view
'output_file': row['output_file'],
'created_at': row['created_at'],
'processed_at': row['processed_at'],
'progress': row['progress'] or 0,
'progress_text': row['progress_text'],
'queue_position': queue_position,
'estimated_start_seconds': estimated_start_seconds
}
@router.get("/api/download/{task_id}")
async def download_task(task_id: str):
result = await crud.get_task_by_id(task_id)
if not result or not result[0]['output_file']:
raise HTTPException(status_code=404, detail="Audio file not found")
row = result[0]
filepath = os.path.join(settings.UPLOAD_FOLDER, row['output_file'])
if not os.path.exists(filepath):
raise HTTPException(status_code=404, detail="File missing on server")
return FileResponse(filepath, media_type="audio/wav", filename=f"tts_{task_id}.wav")
@router.get("/health")
async def health():
return {
'status': 'healthy',
'service': 'tts-runner',
'worker_running': is_worker_running()
}