Grinding commited on
Commit
27510ea
·
verified ·
1 Parent(s): f1473c1

Create app/main.py

Browse files
Files changed (1) hide show
  1. app/main.py +82 -0
app/main.py ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI, UploadFile, File, HTTPException, BackgroundTasks
2
+ from fastapi.middleware.cors import CORSMiddleware
3
+ import uuid
4
+ from . import processing
5
+ from .models import TaskStatus
6
+ import os
7
+ import shutil
8
+ from pathlib import Path
9
+
10
+ app = FastAPI()
11
+
12
+ # Configure CORS - In production, restrict this to your frontend's domain
13
+ origins = ["*"]
14
+ app.add_middleware(
15
+ CORSMiddleware,
16
+ allow_origins=origins,
17
+ allow_credentials=True,
18
+ allow_methods=["*"],
19
+ allow_headers=["*"],
20
+ )
21
+
22
+ tasks = {}
23
+ TEMP_DIR = Path("temp_audio")
24
+ TEMP_DIR.mkdir(exist_ok=True)
25
+
26
+ # Define allowed file extensions and max size (50MB)
27
+ ALLOWED_EXTENSIONS = {".wav", ".mp3", ".m4a", ".ogg", ".flac"}
28
+ MAX_FILE_SIZE = 50 * 1024 * 1024
29
+
30
+ @app.post("/upload")
31
+ async def upload_audio_file(background_tasks: BackgroundTasks, file: UploadFile = File(...)):
32
+ """
33
+ Receives an audio file, saves it temporarily to disk, and starts the
34
+ processing pipeline in the background. Includes validation for file type and size.
35
+ """
36
+ # Validation: File Extension
37
+ file_ext = Path(file.filename).suffix.lower()
38
+ if file_ext not in ALLOWED_EXTENSIONS:
39
+ raise HTTPException(
40
+ status_code=400,
41
+ detail=f"Invalid audio format. Allowed formats: {', '.join(ALLOWED_EXTENSIONS)}"
42
+ )
43
+
44
+ # Validation: File Size
45
+ # We read the file into memory once to check size and then save it.
46
+ # This is a trade-off for validation. For extremely large files (>1GB),
47
+ # a streaming validator would be better, but this is fine for a 50MB limit.
48
+ file_content = await file.read()
49
+ if len(file_content) > MAX_FILE_SIZE:
50
+ raise HTTPException(status_code=413, detail="File too large. Limit is 50MB.")
51
+
52
+ # Reset file pointer before saving
53
+ await file.seek(0)
54
+
55
+ task_id = str(uuid.uuid4())
56
+ tasks[task_id] = {"status": "processing", "result": None}
57
+
58
+ file_path = TEMP_DIR / f"{task_id}{file_ext}"
59
+
60
+ try:
61
+ with open(file_path, "wb") as buffer:
62
+ shutil.copyfileobj(file.file, buffer)
63
+ finally:
64
+ file.file.close()
65
+
66
+ background_tasks.add_task(processing.run_pipeline, task_id, file_path, tasks)
67
+
68
+ return {"task_id": task_id}
69
+
70
+ @app.get("/status/{task_id}", response_model=TaskStatus)
71
+ async def get_task_status(task_id: str):
72
+ task = tasks.get(task_id)
73
+ if not task:
74
+ raise HTTPException(status_code=404, detail="Task not found")
75
+ return TaskStatus(**task)
76
+
77
+ @app.get("/result/{task_id}")
78
+ async def get_task_result(task_id: str):
79
+ task = tasks.get(task_id)
80
+ if not task or task.get("status") != "complete":
81
+ raise HTTPException(status_code=404, detail="Result not yet available or task not found")
82
+ return task.get("result")