File size: 4,068 Bytes
12832d8
b10856a
 
12832d8
b10856a
 
cfdd7b3
e627b57
6fdf170
 
b10856a
bfa2a8d
cfdd7b3
12832d8
34caeeb
 
 
 
6fdf170
 
 
 
 
29f5dfb
fb62834
 
6fdf170
 
12832d8
b10856a
 
 
bfa2a8d
 
 
 
f5884fa
b10856a
 
a50f65d
 
 
b10856a
a50f65d
 
 
 
 
 
 
 
2fbc024
 
 
f5884fa
 
 
 
b10856a
bfa2a8d
 
 
 
 
a50f65d
2fbc024
a50f65d
 
bfa2a8d
2fbc024
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b10856a
 
 
 
bfa2a8d
b10856a
 
 
 
 
2fbc024
b10856a
bfa2a8d
a50f65d
bfa2a8d
 
 
0bd64ff
b10856a
12832d8
6fdf170
b10856a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles
from fastapi.responses import FileResponse
import uvicorn
import os
from pathlib import Path
import mimetypes

from utils import log
from chat_handler import router as chat_router  # ← start_session & chat
from admin_routes import router as admin_router  # ← Admin API endpoints
from spark_startup import run_in_thread
from session import session_store  # ← Import session_store

# Fix MIME types for JavaScript files
mimetypes.add_type("application/javascript", ".js")
mimetypes.add_type("text/css", ".css")

app = FastAPI(
    title="Flare Orchestration Service",
    version="0.1.0",
    description="LLM-driven intent & API flow engine (bootstrap)",
)

run_in_thread()

# ---------------- Core chat/session routes --------------------------
app.include_router(chat_router)

# ---------------- Admin API routes ----------------------------------
app.include_router(admin_router)

# ---------------- Health probe (HF Spaces watchdog) -----------------
@app.get("/")
def health_check():
    return {"status": "ok"}

# ---------------- Serve Angular UI if exists ------------------------
static_path = Path("static")
log(f"πŸ” Checking for static directory at: {static_path.absolute()}")
log(f"πŸ” Static directory exists: {static_path.exists()}")

if static_path.exists() and static_path.is_dir():
    # List files in static directory
    files = list(static_path.iterdir())
    log(f"πŸ“ Files in static directory: {[f.name for f in files]}")
    
    # Check for index.html
    index_path = static_path / "index.html"
    log(f"πŸ” index.html exists: {index_path.exists()}")
    
    # Mount entire static directory
    app.mount("/static", StaticFiles(directory="static"), name="static")
    
    # Serve static files (Angular assets) - only if assets directory exists
    assets_path = static_path / "assets"
    if assets_path.exists() and assets_path.is_dir():
        app.mount("/assets", StaticFiles(directory=str(assets_path)), name="assets")
    
    # Root path - serve index.html
    @app.get("/")
    async def serve_root():
        index_path = static_path / "index.html"
        if index_path.exists():
            log("πŸ“„ Serving index.html")
            return FileResponse(str(index_path), media_type="text/html")
        log("⚠️ index.html not found, returning health check")
        return {"status": "ok", "sessions": len(session_store._sessions)}  # Fallback to health check
    
    # Serve JS files with correct MIME type
    @app.get("/{filename:path}.js")
    async def serve_js(filename: str):
        js_path = static_path / f"{filename}.js"
        if js_path.exists():
            return FileResponse(str(js_path), media_type="application/javascript")
        return {"error": "JS file not found"}, 404
    
    # Serve CSS files with correct MIME type
    @app.get("/{filename:path}.css")
    async def serve_css(filename: str):
        css_path = static_path / f"{filename}.css"
        if css_path.exists():
            return FileResponse(str(css_path), media_type="text/css")
        return {"error": "CSS file not found"}, 404
    
    # Catch-all route for Angular routing (must be last!)
    @app.get("/{full_path:path}")
    async def serve_angular(full_path: str):
        # Don't catch API routes
        if full_path.startswith("api/") or full_path in ["start_session", "chat", "health"]:
            return {"error": "Not found"}, 404
        
        # Return Angular index.html for all other routes
        index_path = static_path / "index.html"
        if index_path.exists():
            return FileResponse(str(index_path), media_type="text/html")
        return {"error": "UI not found"}, 404
else:
    log("⚠️ Static directory not found")
    # No UI built, just health endpoint
    @app.get("/")
    def health_check():
        return {"status": "ok", "message": "UI not found. Build Angular app first."}

if __name__ == "__main__":
    log("🌐 Starting Flare backend …")
    uvicorn.run(app, host="0.0.0.0", port=7860)