File size: 5,277 Bytes
12832d8
b10856a
 
f6b1e89
12832d8
b10856a
 
cfdd7b3
e627b57
6fdf170
 
385aed6
bfa2a8d
c3bf14b
 
d8f52d8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12832d8
34caeeb
 
 
 
6fdf170
 
 
 
 
29f5dfb
f6b1e89
 
 
 
 
 
 
 
 
 
 
fb62834
385aed6
fb62834
6fdf170
ee25b7a
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles
from fastapi.responses import FileResponse
from fastapi.middleware.cors import CORSMiddleware
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, start_cleanup_task
from spark_startup import run_in_thread
from session import session_store, start_session_cleanup

from config_provider import ConfigProvider

# ===================== Environment Setup =====================
def setup_environment():
    """Setup environment based on work_mode"""
    cfg = ConfigProvider.get()
    
    log("=" * 60)
    log(f"πŸš€ Flare Starting in {cfg.global_config.work_mode.upper()} mode")
    log("=" * 60)
    
    if cfg.global_config.is_cloud_mode():
        log("☁️  Cloud Mode: Using HuggingFace Secrets")
        log("πŸ“Œ Required secrets: JWT_SECRET, FLARE_TOKEN_KEY, SPARK_TOKEN")
    else:
        log("🏒 On-Premise Mode: Using .env file")
        if not Path(".env").exists():
            log("⚠️  WARNING: .env file not found!")
            log("πŸ“Œ Copy .env.example to .env and configure it")

# Run setup
setup_environment()

# 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)",
)

# CORS for development
if os.getenv("ENVIRONMENT") == "development":
    app.add_middleware(
        CORSMiddleware,
        allow_origins=["http://localhost:4200"],  # Angular dev server
        allow_credentials=True,
        allow_methods=["*"],
        allow_headers=["*"],
    )
    log("πŸ”§ CORS enabled for development")
    
run_in_thread()
start_cleanup_task()  # Activity log cleanup

# ---------------- Core chat/session routes --------------------------
app.include_router(chat_router, prefix="/api")

# ---------------- 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)