Upload endpoint and temp file hygiene

FastAPI makes multipart uploads trivial. You type-annotate a parameter as UploadFile and the framework does the parsing. The tricky part is temp file hygiene. Whisper reads from a file path, so you buffer the upload to disk. Now you own a file that must get deleted, even if transcription crashes.

backend/app.py
python
import os
import tempfile
from typing import Annotated
from fastapi import FastAPI, File, HTTPException, UploadFile

@app.post("/api/transcribe")
async def transcribe_audio(audio: Annotated[UploadFile, File()]):
    if not service:
        raise HTTPException(status_code=503, detail="Service not ready")

    suffix = os.path.splitext(audio.filename)[1] or ".webm"
    with tempfile.NamedTemporaryFile(delete=False, suffix=suffix) as tmp:
        content = await audio.read()
        tmp.write(content)
        tmp_path = tmp.name

    try:
        raw_text = service.transcribe(tmp_path)
        return {"success": True, "text": raw_text}
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Transcription failed: {str(e)}") from e
    finally:
        if os.path.exists(tmp_path):
            os.unlink(tmp_path)

NamedTemporaryFile with delete=False gives us a path we can pass to Whisper. The try/finally guarantees the file is removed even if transcription raises. Skipping this cleanup fills /tmp and eventually kills the server.

By default Python deletes the file when the context manager exits. That would happen before we run Whisper. delete=False keeps the file alive until we explicitly remove it in the finally block, after transcription is done.

Quiz: Quiz

Loading practice…