audiotonotes / app.py
Archis
add
c3d777a
from fastapi import FastAPI, HTTPException, status # Import HTTPException and status
from fastapi.responses import JSONResponse
from pydantic import BaseModel # Import BaseModel for input validation
import subprocess
import json
import os # Just in case for more complex subprocess env
# Pydantic model for request body validation
class AudioURL(BaseModel):
audioUrl: str
app = FastAPI()
@app.get("/")
async def root(): # Make root async for consistency, though not strictly necessary here
return {"message": "AudioToNotes backend is live"}
@app.post("/analyze")
async def analyze(audio_input: AudioURL): # Use Pydantic model for input
audio_url = audio_input.audioUrl
# Pydantic already handles checking if audioUrl is present and is a string.
# So, the manual 'if not audio_url' check is no longer strictly necessary here,
# as FastAPI would return a 422 error automatically if it's missing or wrong type.
try:
# Run audiotonotes.py
# 'check=True' will raise a CalledProcessError if audiotonotes.py returns a non-zero exit code
result = subprocess.run(
["python3", "audiotonotes.py", audio_url],
capture_output=True,
text=True,
check=True, # This is key: it raises an exception if audiotonotes.py fails
timeout=300 # Increased timeout to 5 minutes (300 seconds) - adjust as needed
)
# If we reach here, audiotonotes.py ran successfully (return code 0)
# We expect its output to stdout to be valid JSON
try:
structured_notes = json.loads(result.stdout)
return JSONResponse(content=structured_notes)
except json.JSONDecodeError:
# This means audiotonotes.py ran, but didn't output valid JSON to stdout
print(f"audiotonotes.py successful but invalid JSON output: {result.stdout}")
print(f"audiotonotes.py stderr (if any): {result.stderr}")
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Audio analysis completed, but output is not valid JSON."
)
except subprocess.CalledProcessError as e:
# This means audiotonotes.py ran, but exited with a non-zero status code (an error occurred within it)
print(f"audiotonotes.py failed with exit code {e.returncode}. Stderr: {e.stderr}")
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Audio analysis script failed: {e.stderr.strip()}"
)
except subprocess.TimeoutExpired:
print("Timeout while processing audio.")
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail="Timeout while processing audio. The analysis took too long."
)
except Exception as e:
# Catch any other unexpected errors
print(f"An unexpected error occurred: {e}")
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"An unexpected server error occurred: {str(e)}"
)
# This block is for local development testing.
# On Hugging Face Spaces with Docker SDK, the CMD in Dockerfile will start uvicorn.
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=7860)