import whisper import tempfile import os import httpx from fastapi import FastAPI, UploadFile, File, Form from fastapi.responses import JSONResponse, HTMLResponse from fastapi.middleware.cors import CORSMiddleware import uvicorn app = FastAPI(title="Whisper Transcription API") print("Loading Whisper model...") model = whisper.load_model("base") print("Model loaded.") app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"], ) @app.get("/", response_class=HTMLResponse) async def root(): return """ Whisper Transcription API

🎙️ Whisper Transcription API

Status: Running

Endpoints:

""" @app.post("/transcribe") async def transcribe( file: UploadFile = File(...), language: str = Form(default="auto") ): suffix = os.path.splitext(file.filename)[-1] if file.filename else ".wav" with tempfile.NamedTemporaryFile(suffix=suffix, delete=False) as tmp: content = await file.read() tmp.write(content) tmp_path = tmp.name try: lang = language if language != "auto" else None result = model.transcribe(tmp_path, language=lang) return JSONResponse({ "text": result["text"].strip(), "language": result.get("language", "unknown"), "segments": [ { "start": round(s["start"], 2), "end": round(s["end"], 2), "text": s["text"].strip() } for s in result.get("segments", []) ] }) except Exception as e: return JSONResponse({"error": str(e)}, status_code=500) finally: os.unlink(tmp_path) @app.post("/transcribe-url") async def transcribe_url( url: str = Form(...), language: str = Form(default="auto") ): try: async with httpx.AsyncClient(timeout=60, follow_redirects=True) as client: r = await client.get(url, headers={ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", "Accept": "*/*", "Accept-Language": "en-US,en;q=0.9", "Referer": "https://www.google.com/" }) r.raise_for_status() except Exception as e: return JSONResponse({"error": f"Failed to download: {str(e)}"}, status_code=400) ext = os.path.splitext(url.split("?")[0])[-1] or ".mp3" with tempfile.NamedTemporaryFile(suffix=ext, delete=False) as tmp: tmp.write(r.content) tmp_path = tmp.name try: lang = language if language != "auto" else None result = model.transcribe(tmp_path, language=lang) return JSONResponse({ "text": result["text"].strip(), "language": result.get("language", "unknown"), "segments": [ { "start": round(s["start"], 2), "end": round(s["end"], 2), "text": s["text"].strip() } for s in result.get("segments", []) ] }) except Exception as e: return JSONResponse({"error": str(e)}, status_code=500) finally: os.unlink(tmp_path) @app.get("/health") async def health(): return {"status": "ok", "model": "whisper-base"} if __name__ == "__main__": uvicorn.run(app, host="0.0.0.0", port=7860)