scenex-analysis / main.py
JonSnow1512's picture
Upload 5 files
2e32eaa verified
Raw
History Blame Contribute Delete
2.4 kB
from fastapi import FastAPI, File, UploadFile, Request
from fastapi.responses import StreamingResponse, JSONResponse
from fastapi.middleware.cors import CORSMiddleware
from PIL import Image
import io
import os
from datetime import datetime
from dotenv import load_dotenv
from analyzer import CrimeSceneAnalyzer
# Load environment variables from the project root .env
load_dotenv(dotenv_path=os.path.join(os.path.dirname(__file__), '..', '.env'))
app = FastAPI()
# Allow the Express backend and the frontend dev server to call this service.
# In production the AI model is only called by the Express proxy, so the
# Express server origin (or "*" when credentials aren't needed) is sufficient.
_frontend_url = os.environ.get("FRONTEND_URL", "http://localhost:5173")
_backend_url = os.environ.get("VITE_API_BASE_URL", "http://localhost:5000")
app.add_middleware(
CORSMiddleware,
allow_origins=[_frontend_url, _backend_url, "http://localhost:5173", "http://localhost:5000"],
allow_credentials=False,
allow_methods=["*"],
allow_headers=["*"],
)
analyzer = CrimeSceneAnalyzer()
@app.post("/analyze")
async def analyze(file: UploadFile = File(...)):
try:
image_bytes = await file.read()
image_pil = Image.open(io.BytesIO(image_bytes))
except Exception as e:
return JSONResponse(
status_code=400,
content={"error": f"Invalid or corrupted image file. Details: {str(e)}"}
)
# Get analysis result from the AI module
result = analyzer.analyze_scene(image_pil)
if not result or "error" in result:
return JSONResponse(
status_code=500,
content={"error": result.get("error", "AI analysis error") if isinstance(result, dict) else "AI analysis error"}
)
pdf_bytes = result.get("pdf_bytes")
if not pdf_bytes:
return JSONResponse(
status_code=500,
content={"error": "No PDF bytes produced by AI analysis."}
)
# Wrap the raw bytes in an in-memory file-like object
pdf_stream = io.BytesIO(pdf_bytes)
filename = f"CSR_{datetime.now().strftime('%Y%m%d_%H%M%S')}.pdf"
return StreamingResponse(
content=pdf_stream,
media_type="application/pdf",
headers={"Content-Disposition": f"attachment; filename={filename}"}
)