Files
transcript/app/main.py
2026-03-23 19:25:34 +01:00

80 lines
1.9 KiB
Python

import os
from contextlib import asynccontextmanager
from pathlib import Path
from fastapi import FastAPI, HTTPException, BackgroundTasks
from fastapi.responses import FileResponse
from pydantic import BaseModel
from app import downloader
STATIC_DIR = Path(__file__).parent / "static"
AUDIO_TMP_DIR = Path("/tmp/apoena-audio")
@asynccontextmanager
async def lifespan(app: FastAPI):
AUDIO_TMP_DIR.mkdir(parents=True, exist_ok=True)
yield
app = FastAPI(title="apoena-transcript", lifespan=lifespan)
class ExtractAudioRequest(BaseModel):
url: str
@app.get("/health")
async def health():
return {"status": "ok"}
@app.get("/worker.js")
async def worker_js():
return FileResponse(STATIC_DIR / "worker.js", media_type="application/javascript")
@app.get("/sw.js")
async def sw_js():
return FileResponse(STATIC_DIR / "sw.js", media_type="application/javascript")
@app.get("/manifest.json")
async def manifest():
return FileResponse(STATIC_DIR / "manifest.json", media_type="application/manifest+json")
@app.get("/icon.svg")
async def icon():
return FileResponse(STATIC_DIR / "icon.svg", media_type="image/svg+xml")
@app.get("/icon-maskable.svg")
async def icon_maskable():
return FileResponse(STATIC_DIR / "icon-maskable.svg", media_type="image/svg+xml")
@app.post("/extract-audio")
async def extract_audio(body: ExtractAudioRequest, background_tasks: BackgroundTasks):
try:
audio_path = await downloader.extract_audio(body.url)
except RuntimeError as e:
raise HTTPException(status_code=422, detail=str(e))
background_tasks.add_task(_delete_file, audio_path)
return FileResponse(audio_path, media_type="audio/mpeg", filename="audio.mp3")
def _delete_file(path):
try:
os.unlink(path)
except OSError:
pass
@app.get("/")
async def index():
return FileResponse(STATIC_DIR / "index.html")