Alpha123B commited on
Commit
9b8fd21
·
verified ·
1 Parent(s): fa77e0f

Add FastAPI main app

Browse files
Files changed (1) hide show
  1. backend/main.py +102 -0
backend/main.py ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """ViralClipFactory - FastAPI Application Entry Point."""
2
+ import os
3
+ import logging
4
+ from pathlib import Path
5
+ from contextlib import asynccontextmanager
6
+ from fastapi import FastAPI
7
+ from fastapi.staticfiles import StaticFiles
8
+ from fastapi.middleware.cors import CORSMiddleware
9
+ from fastapi.responses import FileResponse
10
+
11
+ from .routers import ingest, analyze, generate
12
+
13
+ # Configure logging
14
+ logging.basicConfig(
15
+ level=logging.INFO,
16
+ format="%(asctime)s [%(levelname)s] %(name)s: %(message)s"
17
+ )
18
+ logger = logging.getLogger(__name__)
19
+
20
+ # Ensure temp directory exists
21
+ TEMP_DIR = os.environ.get("TEMP_DIR", "/tmp/viralclipfactory")
22
+ Path(TEMP_DIR).mkdir(parents=True, exist_ok=True)
23
+
24
+
25
+ @asynccontextmanager
26
+ async def lifespan(app: FastAPI):
27
+ """App lifespan: startup and shutdown."""
28
+ logger.info("🎬 ViralClipFactory starting up...")
29
+ logger.info(f"Temp directory: {TEMP_DIR}")
30
+ yield
31
+ logger.info("🎬 ViralClipFactory shutting down...")
32
+
33
+
34
+ # Create FastAPI app
35
+ app = FastAPI(
36
+ title="ViralClipFactory",
37
+ description="AI-powered viral short clip generator from long-form video",
38
+ version="1.0.0",
39
+ lifespan=lifespan,
40
+ )
41
+
42
+ # CORS middleware for frontend
43
+ app.add_middleware(
44
+ CORSMiddleware,
45
+ allow_origins=["*"],
46
+ allow_credentials=True,
47
+ allow_methods=["*"],
48
+ allow_headers=["*"],
49
+ )
50
+
51
+ # Include routers
52
+ app.include_router(ingest.router)
53
+ app.include_router(analyze.router)
54
+ app.include_router(generate.router)
55
+
56
+ # Serve frontend static files
57
+ FRONTEND_DIR = Path(__file__).parent.parent / "frontend" / "dist"
58
+ if FRONTEND_DIR.exists():
59
+ app.mount("/assets", StaticFiles(directory=str(FRONTEND_DIR / "assets")), name="static-assets")
60
+
61
+
62
+ @app.get("/api/health")
63
+ async def health_check():
64
+ """Health check endpoint."""
65
+ return {
66
+ "status": "healthy",
67
+ "service": "ViralClipFactory",
68
+ "version": "1.0.0"
69
+ }
70
+
71
+
72
+ @app.get("/api/config")
73
+ async def get_config():
74
+ """Get available configuration options."""
75
+ from .models.schemas import CaptionStyle, ColorGrade, MusicGenre, VoicePreset
76
+
77
+ return {
78
+ "caption_styles": [s.value for s in CaptionStyle],
79
+ "color_grades": [c.value for c in ColorGrade],
80
+ "music_genres": [m.value for m in MusicGenre],
81
+ "voice_presets": [v.value for v in VoicePreset],
82
+ "max_clips": 10,
83
+ "max_upload_mb": 2048,
84
+ "supported_formats": [".mp4", ".mov", ".mkv", ".avi", ".webm"],
85
+ }
86
+
87
+
88
+ # Serve frontend for all non-API routes (SPA)
89
+ @app.get("/{full_path:path}")
90
+ async def serve_frontend(full_path: str):
91
+ """Serve React frontend (SPA fallback)."""
92
+ if FRONTEND_DIR.exists():
93
+ # Try to serve the requested file
94
+ file_path = FRONTEND_DIR / full_path
95
+ if file_path.exists() and file_path.is_file():
96
+ return FileResponse(str(file_path))
97
+ # Fallback to index.html for SPA routing
98
+ index_path = FRONTEND_DIR / "index.html"
99
+ if index_path.exists():
100
+ return FileResponse(str(index_path))
101
+
102
+ return {"message": "Frontend not built. Run 'npm run build' in frontend/"}