-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
87 lines (67 loc) · 2.59 KB
/
Copy pathmain.py
File metadata and controls
87 lines (67 loc) · 2.59 KB
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
import os
import asyncio
import logging
import threading
from contextlib import asynccontextmanager
from fastapi import FastAPI
from fastapi.responses import JSONResponse, RedirectResponse
from fastapi.staticfiles import StaticFiles
from app.api.routes import router as admin_router
from app.mcp.mcp_server import mcp_server
from app.services.database import init_db
from app.services.indexing import run_full_indexing, VAULT_PATH
# Configure logging
logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")
logger = logging.getLogger("contextcortex")
# Initialize database
try:
init_db(VAULT_PATH)
except Exception as e:
logger.error(f"Failed to init DB: {e}")
@asynccontextmanager
async def lifespan(app: FastAPI):
import app.services.indexing as indexer
from app.services.poller import start_poller_daemon, stop_poller_daemon
indexer.main_event_loop = asyncio.get_running_loop()
logger.info("ContextCortex Server starting up...")
try:
threading.Thread(target=run_full_indexing, daemon=True).start()
except Exception as e:
logger.error(f"Startup indexing error: {e}")
try:
start_poller_daemon()
except Exception as e:
logger.error(f"Startup poller daemon error: {e}")
async with mcp_server.session_manager.run():
yield
logger.info("ContextCortex Server shutting down...")
try:
stop_poller_daemon()
except Exception as e:
logger.error(f"Shutdown poller daemon error: {e}")
try:
from app.services.vector_store.manager import VectorStoreManager
VectorStoreManager.reset_instance()
except Exception:
pass
app = FastAPI(title="ContextCortex", version="2.11.0", lifespan=lifespan)
# Include API routes
app.include_router(admin_router)
@app.get("/")
async def root_redirect():
return RedirectResponse(url="/admin/")
www_dir = "frontend/dist" if os.path.exists("frontend/dist/index.html") else "www"
assets_dir = os.path.join(www_dir, "assets") if os.path.exists(os.path.join(www_dir, "assets")) else "www/assets"
app.mount("/admin", StaticFiles(directory=www_dir, html=True), name="admin")
app.mount("/assets", StaticFiles(directory=assets_dir), name="assets")
# Mount FastMCP SSE and Streamable HTTP endpoints
for route in mcp_server.sse_app().routes:
app.routes.append(route)
for route in mcp_server.streamable_http_app().routes:
app.routes.append(route)
@app.get("/health")
async def health():
return JSONResponse(content={"status": "healthy"})
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=3000)