Spaces:
Sleeping
Sleeping
| # app.py | |
| from fastapi import FastAPI, UploadFile, Form, BackgroundTasks | |
| from fastapi.middleware.cors import CORSMiddleware | |
| from fastapi.responses import JSONResponse | |
| from pathlib import Path | |
| import subprocess | |
| import shutil | |
| import time | |
| import traceback | |
| import cloudinary | |
| import cloudinary.uploader | |
| from io import BytesIO | |
| from huggingface_hub import hf_hub_download | |
| app = FastAPI( | |
| title="🚦 VRU Detection & Forecasting API", | |
| description="Backend API for VRU Detection, Tracking & Forecasting pipeline (Hugging Face Spaces Edition)", | |
| version="1.0.0" | |
| ) | |
| # ============================== | |
| # CONFIG | |
| # ============================== | |
| # Configure Cloudinary (you can put these in .env instead) | |
| cloudinary.config( | |
| cloud_name="YOUR_CLOUD_NAME", | |
| api_key="YOUR_API_KEY", | |
| api_secret="YOUR_API_SECRET" | |
| ) | |
| SCRIPTS = [ | |
| ("Video Creation", "video_creation.py"), | |
| ("YOLO + DeepSORT Tracking", "yolo_deepsort_tracker.py"), | |
| ("Excel Generation", "excel_generation.py"), | |
| ("Feature Engineering", "feature_engineering_forecasting.py"), | |
| ("Trajectory Forecasting (Transformer)", "vru_forecasting_transformer.py"), | |
| ("Trajectory Visualization", "animated_visualization.py") | |
| ] | |
| OUTPUT_GIF = Path("trajectory_comparison.gif") | |
| # ============================== | |
| # CORS | |
| # ============================== | |
| app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=["https://vru-detection.vercel.app/"], # later replace with your frontend URL | |
| allow_credentials=True, | |
| allow_methods=["*"], | |
| allow_headers=["*"], | |
| ) | |
| # ============================== | |
| # UTILS | |
| # ============================== | |
| def run_pipeline(input_path: str): | |
| """Sequentially run all VRU pipeline scripts.""" | |
| total = len(SCRIPTS) | |
| progress = [] | |
| for i, (label, script) in enumerate(SCRIPTS): | |
| stage_info = { | |
| "stage": i + 1, | |
| "label": label, | |
| "status": "running", | |
| "progress": round((i + 1) / total, 2) | |
| } | |
| progress.append(stage_info) | |
| try: | |
| result = subprocess.run( | |
| ["python", script, input_path], | |
| capture_output=True, text=True | |
| ) | |
| if result.returncode == 0: | |
| stage_info["status"] = "completed" | |
| stage_info["output"] = result.stdout | |
| else: | |
| stage_info["status"] = "failed" | |
| stage_info["error"] = result.stderr | |
| return {"status": "failed", "progress": progress} | |
| except Exception as e: | |
| stage_info["status"] = "error" | |
| stage_info["error"] = str(e) | |
| return {"status": "failed", "progress": progress} | |
| time.sleep(0.5) | |
| return {"status": "completed", "progress": progress} | |
| # ============================== | |
| # ROUTES | |
| # ============================== | |
| def home(): | |
| return {"message": "🚦 VRU Detection Backend Running on Hugging Face Spaces!"} | |
| async def run_vru_pipeline( | |
| background_tasks: BackgroundTasks, | |
| dataset_name: str = Form(None), | |
| file: UploadFile = None | |
| ): | |
| """ | |
| Run full VRU pipeline. | |
| Accepts either uploaded file or Hugging Face dataset name. | |
| """ | |
| try: | |
| # Handle file upload | |
| if file: | |
| temp_path = Path("uploaded_" + file.filename) | |
| with open(temp_path, "wb") as buffer: | |
| shutil.copyfileobj(file.file, buffer) | |
| input_path = str(temp_path) | |
| # Handle Hugging Face dataset file | |
| elif dataset_name: | |
| input_path = hf_hub_download( | |
| repo_id=dataset_name, | |
| filename="ring_side_left/video.mp4" # Adjust if structure differs | |
| ) | |
| else: | |
| return JSONResponse({"error": "Please provide a dataset_name or upload a file."}, status_code=400) | |
| # Run pipeline | |
| result = run_pipeline(input_path) | |
| response = {"input_path": input_path, "result": result} | |
| # Upload visualization if available | |
| if OUTPUT_GIF.exists(): | |
| upload_result = cloudinary.uploader.upload( | |
| str(OUTPUT_GIF), | |
| resource_type="image", | |
| folder="vru_results/" | |
| ) | |
| response["visualization_url"] = upload_result["secure_url"] | |
| return JSONResponse(response) | |
| except Exception as e: | |
| return JSONResponse( | |
| {"error": str(e), "trace": traceback.format_exc()}, | |
| status_code=500 | |
| ) | |