TanishkOrion's picture
final pushing
c2888ff
Raw
History Blame Contribute Delete
8.6 kB
# from fastapi import FastAPI, UploadFile, File
# from fastapi.middleware.cors import CORSMiddleware
# from predict_vitals import predict_vitals
# import shutil
# import os
# app = FastAPI()
# origins = [
# "http://localhost:5173" # frontend in development # your production frontend
# ]
# # ✅ Enable CORS
# app.add_middleware(
# CORSMiddleware,
# allow_origins=origins, # Or restrict to ["http://localhost:5173"]
# allow_credentials=True,
# allow_methods=["*"],
# allow_headers=["*"],
# )
# @app.post("/analyze_video/")
# async def analyze_video(file: UploadFile = File(...)):
# try:
# temp_dir = "uploads"
# os.makedirs(temp_dir, exist_ok=True)
# temp_path = os.path.join(temp_dir, file.filename)
# with open(temp_path, "wb") as buffer:
# shutil.copyfileobj(file.file, buffer)
# result = predict_vitals(video_path=temp_path)
# os.remove(temp_path)
# print("Video received:", temp_path)
# print("Model output:", result)
# return result
# except Exception as e:
# return {"error": str(e)}
# from fastapi import FastAPI, UploadFile, File, HTTPException
# from fastapi.responses import JSONResponse
# import uvicorn
# import shutil
# import os
# import uuid
# import logging
# from predict_vitals import predict_vitals
# # --- Basic Configuration ---
# # Set up a logger for better debugging and monitoring in production
# logging.basicConfig(level=logging.INFO)
# logger = logging.getLogger(__name__)
# # Create the FastAPI app instance
# app = FastAPI(
# title="BeatSync Vital Signs Model Service",
# description="A dedicated API to analyze video files and extract heart rate and breathing rate using the MTTS-CAN model.",
# version="1.0.0"
# )
# # Define the directory to store temporary video files
# TEMP_DIR = "temp_videos"
# os.makedirs(TEMP_DIR, exist_ok=True)
# # --- API Endpoint Definition ---
# @app.post("/analyze_video/")
# async def analyze_video(file: UploadFile = File(...)):
# """
# This endpoint accepts a video file, processes it to predict vital signs
# (heart rate and breathing rate), and returns the results.
# """
# # Create a unique filename to prevent conflicts if multiple users upload at once
# unique_filename = f"{uuid.uuid4()}_{file.filename}"
# temp_video_path = os.path.join(TEMP_DIR, unique_filename)
# try:
# # --- 1. Save the uploaded video to a temporary file ---
# logger.info(f"Receiving file: {file.filename}")
# with open(temp_video_path, "wb") as buffer:
# shutil.copyfileobj(file.file, buffer)
# logger.info(f"File saved temporarily to: {temp_video_path}")
# # --- 2. Call the core prediction logic from predict_vitals.py ---
# logger.info("Starting vital signs prediction...")
# # The predict_vitals function will handle preprocessing and model inference
# result = predict_vitals(video_path=temp_video_path)
# logger.info(f"Prediction successful. Result: {result}")
# # --- 3. Validate the model's output ---
# # Ensure the result is a dictionary and contains the expected keys
# if not isinstance(result, dict) or "heart_rate" not in result or "breathing_rate" not in result:
# logger.error(f"Invalid output format from model: {result}")
# raise HTTPException(
# status_code=500,
# detail="Model produced an unexpected output format."
# )
# # --- 4. Return the successful result ---
# return JSONResponse(
# status_code=200,
# content=result
# )
# except (IOError, ValueError, HTTPException) as e:
# # Catch specific, known errors (e.g., video too short, no face detected)
# logger.error(f"A known error occurred during processing: {e}")
# # Forward the specific error message to the client
# raise HTTPException(status_code=400, detail=str(e))
# except Exception as e:
# # Catch any other unexpected errors during the process
# logger.exception(f"An unexpected error occurred for file {file.filename}: {e}")
# # Return a generic 500 Internal Server Error to hide implementation details
# raise HTTPException(
# status_code=500,
# detail="An internal server error occurred during video analysis."
# )
# finally:
# # --- 5. Clean up the temporary file ---
# # This block ensures the temporary video is deleted, even if an error occurred.
# if os.path.exists(temp_video_path):
# os.remove(temp_video_path)
# logger.info(f"Cleaned up temporary file: {temp_video_path}")
# # --- Health Check Endpoint ---
# @app.get("/")
# def read_root():
# """A simple health check endpoint to confirm the service is running."""
# return {"status": "Video Model Service is running"}
# # --- To run this server locally for testing ---
# # Use the command: uvicorn server:app --host 0.0.0.0 --port 8000 --reload
# if __name__ == "__main__":
# uvicorn.run(app, host="0.0.0.0", port=8000)
# from fastapi import FastAPI, UploadFile, File, HTTPException
# from fastapi.responses import JSONResponse
# import uvicorn
# import logging
# from predict_vitals import predict_vitals
# from fastapi.middleware.cors import CORSMiddleware # 1. ADD THIS IMPORT
# app = FastAPI(
# title="BeatSync Video Model Service",
# description="An API to process video files and predict vital signs.",
# version="1.0.0"
# )
# # 2. ADD THIS ENTIRE BLOCK
# # This allows your API Gateway on Render to communicate with this service.
# # --------------------------------------------------------------------------
# app.add_middleware(
# CORSMiddleware,
# allow_origins=["*"], # Allows all origins
# allow_credentials=True,
# allow_methods=["*"], # Allows all methods
# allow_headers=["*"], # Allows all headers
# )
# # --------------------------------------------------------------------------
# logging.basicConfig(level=logging.INFO)
# logger = logging.getLogger(__name__)
# @app.post("/predict/")
# async def predict(video: UploadFile = File(...)):
# if not video.filename.endswith('.mp4'):
# raise HTTPException(status_code=400, detail="Invalid file format. Please upload an MP4 video.")
# try:
# # Save the uploaded video file temporarily
# video_path = f"/tmp/{video.filename}"
# with open(video_path, "wb") as buffer:
# buffer.write(await video.read())
# logger.info(f"Processing video: {video_path}")
# # Get predictions
# predictions = predict_vitals(video_path)
# return JSONResponse(content=predictions)
# except Exception as e:
# logger.exception(f"An error occurred during prediction: {e}")
# raise HTTPException(status_code=500, detail=str(e))
# @app.get("/")
# def read_root():
# return {"status": "Video Model Service is running"}
# if __name__ == "__main__":
# uvicorn.run(app, host="0.0.0.0", port=8002) # This port is for local dev only
from fastapi import FastAPI, UploadFile, File, HTTPException
import uvicorn
import logging
import os
from predict_vitals import predict_vitals
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
# This is critical: It allows your frontend on Render to call this service
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_methods=["*"],
allow_headers=["*"],
)
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
@app.post("/predict/")
async def predict(video: UploadFile = File(...)):
video_path = f"/tmp/{os.urandom(8).hex()}_{video.filename}"
try:
with open(video_path, "wb") as buffer:
buffer.write(await video.read())
logger.info(f"Processing video: {video_path}")
predictions = predict_vitals(video_path)
return predictions
except Exception as e:
logger.exception(f"An error occurred during prediction: {e}")
raise HTTPException(status_code=500, detail=str(e))
finally:
# This ensures the video is always deleted after processing
if os.path.exists(video_path):
os.remove(video_path)
logger.info(f"Cleaned up temporary video file: {video_path}")
@app.get("/")
def read_root():
return {"status": "Video Model Service is running"}