hardbanrecords/Metadata-Engine
0
1import starlette.formparsers2import logging3import os4from fastapi import FastAPI5from fastapi.middleware.cors import CORSMiddleware6from fastapi.staticfiles import StaticFiles7from fastapi.responses import HTMLResponse, FileResponse8from app.config import settings9 10# === ULTIMATE INFRASTRUCTURE PATCH ===11LIMIT_MB = 10012starlette.formparsers.MultiPartParser.max_part_size = LIMIT_MB * 1024 * 102413starlette.formparsers.MultiPartParser.max_fields_size = LIMIT_MB * 1024 * 102414 15logging.basicConfig(level=logging.INFO)16logger = logging.getLogger("app.main")17 18from app.routes import (19 proxy_router, spotify_router, lastfm_router, discogs_router,20 audd_router, auth_router, history_router, quota_router,21 tagging_router, ddex_router, analysis_router, generative_router,22 health_router, mir_router, ai_proxy_router, cwr_router,23 batch_router, system_router, webhook24)25from app.routes.pinata import router as pinata_router26from app.routes.fresh_analysis import router as fresh_router27from app.routes.export import router as export_router28from app.routes.tools import router as tools_router29from app.routes.v2.ipfs import router as ipfs_v2_router30 31app = FastAPI()32 33app.add_middleware(34 CORSMiddleware,35 allow_origins=["*"],36 allow_credentials=True,37 allow_methods=["*"],38 allow_headers=["*"],39)40 41# API Routes42app.include_router(proxy_router, prefix="/api")43app.include_router(health_router, prefix="/api")44app.include_router(mir_router, prefix="/api")45app.include_router(spotify_router, prefix="/api")46app.include_router(lastfm_router, prefix="/api")47app.include_router(discogs_router, prefix="/api")48app.include_router(audd_router, prefix="/api")49app.include_router(auth_router, prefix="/api")50app.include_router(history_router, prefix="/api")51app.include_router(quota_router, prefix="/api")52app.include_router(batch_router, prefix="/api")53app.include_router(tagging_router, prefix="/api")54app.include_router(ddex_router, prefix="/api")55app.include_router(analysis_router, prefix="/api")56app.include_router(generative_router, prefix="/api")57app.include_router(ai_proxy_router, prefix="/api")58app.include_router(pinata_router, prefix="/api")59app.include_router(cwr_router, prefix="/api")60app.include_router(fresh_router, prefix="/api")61app.include_router(export_router, prefix="/api")62app.include_router(system_router, prefix="/api")63app.include_router(tools_router, prefix="/api")64app.include_router(ipfs_v2_router, prefix="/api/v2")65 66@app.get("/api/debug/files")67def debug_files():68 """List files in frontend dist to verify build"""69 import os70 frontend_dist = os.path.join(os.path.dirname(__file__), "..", "frontend", "dist")71 assets_dir = os.path.join(frontend_dist, "assets")72 73 result = {74 "dist_path": frontend_dist,75 "exists": os.path.exists(frontend_dist),76 "files_root": [],77 "assets_path": assets_dir,78 "assets_exists": os.path.exists(assets_dir),79 "files_assets": []80 }81 82 if os.path.exists(frontend_dist):83 result["files_root"] = os.listdir(frontend_dist)84 85 if os.path.exists(assets_dir):86 result["files_assets"] = os.listdir(assets_dir)87 88 return result89 90@app.get("/api/worker_status")91def get_worker_status():92 return {"status": "online", "deployment": "Hugging Face"}93 94# Serve static frontend with DYNAMIC INJECTION95frontend_dist_path = os.path.join(os.path.dirname(__file__), "..", "frontend", "dist")96 97# Mount assets (CSS, JS, Images)98if os.path.exists(frontend_dist_path):99 # Mount assets folder explicitly100 assets_path = os.path.join(frontend_dist_path, "assets")101 if os.path.exists(assets_path):102 app.mount("/assets", StaticFiles(directory=assets_path), name="assets")103 104def get_injected_index():105 path = os.path.join(frontend_dist_path, "index.html")106 if not os.path.exists(path):107 return "<h1>Frontend build not found.</h1>"108 109 with open(path, 'r', encoding='utf-8') as f:110 content = f.read()111 112 import json113 s_url = settings.SUPABASE_URL or ""114 s_key = settings.SUPABASE_KEY or ""115 acr_host = settings.ACR_HOST or ""116 acr_key = settings.ACR_ACCESS_KEY or ""117 acr_secret = settings.ACR_ACCESS_SECRET or ""118 gemini_key = settings.GEMINI_API_KEY or ""119 120 logger.info(f"Injecting Config: Supabase={'set' if s_url else 'MISSING'}, ACR={'set' if acr_key else 'MISSING'}")121 122 env_script = f"""<script>123 window.VITE_SUPABASE_URL = {json.dumps(s_url)};124 window.VITE_SUPABASE_ANON_KEY = {json.dumps(s_key)};125 window.VITE_ACR_HOST = {json.dumps(acr_host)};126 window.VITE_ACR_ACCESS_KEY = {json.dumps(acr_key)};127 window.VITE_ACR_ACCESS_SECRET = {json.dumps(acr_secret)};128 window.VITE_GEMINI_API_KEY = {json.dumps(gemini_key)};129 console.log("MME: Runtime Config Injected");130 </script>"""131 return content.replace("<head>", f"<head>{env_script}")132 133@app.get("/")134async def serve_root():135 return HTMLResponse(get_injected_index())136 137# Support for SPA routing - capture everything else that's not a static file or API138@app.get("/{path:path}")139async def catch_all(path: str):140 # 1. Check if file exists in frontend/dist (e.g. favicon.ico, robots.txt)141 # We only serve from the dist folder.142 full_path = os.path.join(frontend_dist_path, path)143 if os.path.exists(full_path) and os.path.isfile(full_path):144 return FileResponse(full_path)145 146 # 2. If it looks like a file (has extension) but doesn't exist locally -> 404147 if "." in path.split("/")[-1]:148 return HTMLResponse(content=f"Asset not found: {path}", status_code=404)149 150 # 3. Otherwise, it's a React route -> serve index.html151 return HTMLResponse(get_injected_index())152 