Repository navigation
Expand file tree
/
Copy pathmain.py
More file actions
135 lines (112 loc) · 3.94 KB
/
Copy pathmain.py
File metadata and controls
135 lines (112 loc) · 3.94 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
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
import sys
import asyncio
import os
from datetime import datetime
from contextlib import asynccontextmanager
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from backend.app.router import router as query_router
from backend.utils.market_data import init_market_data
from backend.shared.logger import get_logger
from fastapi.staticfiles import StaticFiles
from backend.retrieval.retriever import load_vectorstore, close_vectorstore
from backend.shared.constants import (
VECTORSTORE_PATH_STR,
FRONTEND_RENDERER_DIR,
FRONTEND_ASSETS_DIR,
)
if sys.platform == "win32":
# Use ProactorEventLoop for Windows subprocess support
asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy())
logger = get_logger("MAIN")
@asynccontextmanager
async def lifespan(app: FastAPI):
"""
Lifespan event handler for startup and shutdown.
"""
# Startup
try:
if not os.path.exists(VECTORSTORE_PATH_STR):
os.makedirs(VECTORSTORE_PATH_STR)
logger.info(f"Vectorstore directory created at: {VECTORSTORE_PATH_STR}")
# Check if the vectorstore files exist, if not, we can't load it.
# The user should upload files first.
if os.path.exists(VECTORSTORE_PATH_STR):
logger.info("Loading vectorstore...")
await load_vectorstore(VECTORSTORE_PATH_STR)
logger.info("Vectorstore loaded successfully.")
else:
logger.warning("Vectorstore not found. Please upload files to create it.")
except Exception as e:
import traceback
logger.error(f"Error loading vectorstore: {e}")
logger.error(f"Traceback: {traceback.format_exc()}")
try:
await init_market_data()
logger.info("Market data initialized successfully")
except Exception as e:
logger.error(f"Error initializing market data: {e}")
try:
from backend.core.checkpointer import setup_checkpointer
checkpointer_success = await setup_checkpointer()
if checkpointer_success:
logger.info("✅ AsyncSqlite checkpointer initialized successfully")
else:
logger.warning(
"AsyncSqlite checkpointer initialization failed. Agents will run without persistent state."
)
except Exception as e:
logger.error(f"Error setting up checkpointer: {e}")
logger.warning("Agents will run without persistent checkpointing")
yield
# Shutdown
try:
logger.info("Shutting down AIris Backend API...")
from backend.core.checkpointer import close_checkpointer
await close_checkpointer()
await close_vectorstore()
except Exception as e:
logger.error(f"Error during shutdown: {e}")
logger.info("Starting AIris Backend API...")
# Fast API app start
app = FastAPI(
title="AIris Local RAG API",
version="0.1.0",
description="Generative AI for Local Data",
lifespan=lifespan,
)
# Serve UI static files
app.mount(
"/static",
StaticFiles(directory=str(FRONTEND_RENDERER_DIR)),
name="static",
)
app.mount("/assets", StaticFiles(directory=str(FRONTEND_ASSETS_DIR)), name="assets")
# The desktop renderer has an opaque `null` origin when loaded from file://.
app.add_middleware(
CORSMiddleware,
allow_origins=[
"null",
"http://127.0.0.1:8001",
"http://localhost:8001",
],
allow_credentials=False,
allow_methods=["GET", "POST", "PUT", "DELETE", "OPTIONS"],
allow_headers=["Content-Type"],
)
@app.get("/")
async def root():
return {"message": "AIris Backend API", "version": "0.1.0", "status": "running"}
@app.get("/health")
async def health_check():
"""
Health check endpoint that returns JSON status
"""
return {
"status": "healthy",
"timestamp": datetime.now().isoformat(),
"service": "AIris Backend API",
"version": "0.1.0",
}
# Connect API routes
app.include_router(query_router, prefix="/api")