htrnguyen/golf-tech-analysis
0
1import os2import shutil3import uuid4from fastapi import FastAPI, UploadFile, File, HTTPException, Request, BackgroundTasks5from fastapi.responses import FileResponse, HTMLResponse6from fastapi.templating import Jinja2Templates7 8app = FastAPI(title="Golf Tech Analysis API")9 10UPLOAD_DIR = "uploads"11TEMPLATES_DIR = "templates"12os.makedirs(UPLOAD_DIR, exist_ok=True)13os.makedirs(TEMPLATES_DIR, exist_ok=True)14 15# Templates16templates = Jinja2Templates(directory=TEMPLATES_DIR)17 18# Import optimized pipeline19from main import analyze_video_fast20from reengineer import reengineer_video21 22 23@app.get("/")24async def root(request: Request):25 """26 Giao diện upload để test (cho developer).27 """28 return templates.TemplateResponse("index.html", {"request": request})29 30 31@app.post("/")32async def analyze_with_video(33 file: UploadFile = File(...), background_tasks: BackgroundTasks = None34):35 """36 UI endpoint: Phân tích + Tạo video có overlay.37 Trả về video để download.38 """39 job_id = str(uuid.uuid4())40 video_ext = os.path.splitext(file.filename)[1]41 video_path = os.path.join(UPLOAD_DIR, f"{job_id}{video_ext}")42 output_dir = os.path.join("output", job_id)43 os.makedirs(output_dir, exist_ok=True)44 45 try:46 # Lưu video47 with open(video_path, "wb") as buffer:48 shutil.copyfileobj(file.file, buffer)49 50 # Phân tích (lưu vào output/)51 master_json = os.path.join(output_dir, "master_data.json")52 result = analyze_video_fast(53 video_path, production=True, output_file=master_json, output_base="output"54 )55 56 # Tạo video có overlay57 output_video = os.path.join(output_dir, "analyzed_video.mp4")58 reengineer_video(master_json, video_path, output_video, production=True)59 60 # Cleanup video gốc61 if os.path.exists(video_path):62 os.remove(video_path)63 64 # Schedule cleanup after response65 def cleanup():66 try:67 if os.path.exists(output_dir):68 shutil.rmtree(output_dir, ignore_errors=True)69 except:70 pass71 72 if background_tasks:73 background_tasks.add_task(cleanup)74 75 # Trả về video file76 return FileResponse(77 output_video, media_type="video/mp4", filename=f"golf_analysis_{job_id}.mp4"78 )79 80 except Exception as e:81 if os.path.exists(video_path):82 os.remove(video_path)83 if os.path.exists(output_dir):84 shutil.rmtree(output_dir, ignore_errors=True)85 raise HTTPException(status_code=500, detail=str(e))86 87 88@app.post("/api/analyze")89async def api_analyze(file: UploadFile = File(...)):90 """91 Pure API endpoint: Chỉ trả JSON, không tạo video.92 Dùng cho app/web production.93 """94 job_id = str(uuid.uuid4())95 video_ext = os.path.splitext(file.filename)[1]96 video_path = os.path.join(UPLOAD_DIR, f"{job_id}{video_ext}")97 98 try:99 # Lưu video tạm thời100 with open(video_path, "wb") as buffer:101 shutil.copyfileobj(file.file, buffer)102 103 # Gọi optimized pipeline (KHÔNG tạo video)104 result = analyze_video_fast(video_path, production=True)105 106 # Cleanup107 if os.path.exists(video_path):108 os.remove(video_path)109 110 return result111 112 except Exception as e:113 if os.path.exists(video_path):114 os.remove(video_path)115 raise HTTPException(status_code=500, detail=str(e))116 117 118# Check health (GET, HEAD)119@app.api_route("/api/health", methods=["GET", "HEAD"])120async def health_check():121 return {"status": "ok"}122 123 124if __name__ == "__main__":125 import uvicorn126 127 uvicorn.run(app, host="0.0.0.0", port=7860)128 