-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.py
More file actions
162 lines (140 loc) Β· 5.76 KB
/
app.py
File metadata and controls
162 lines (140 loc) Β· 5.76 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
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
import sys
import os
import uvicorn
from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles
from fastapi.middleware.cors import CORSMiddleware
from fastapi.responses import RedirectResponse
from contextlib import asynccontextmanager
# Add project root to path
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
from backend.logger import get_logger, init_logger
# Initialize logger configuration immediately
init_logger()
from backend.storage_service import ensure_minio_running
from backend.database.reset_db import reset_database
from backend.storage_service.reset_minio import reset_minio
from backend.database.set_default import set_default
from backend.api import auth, dashboard, emails, tasks, teachers, templates, aggregations, settings, mailbox, files, agent
from backend.scheduler import start_scheduler, stop_scheduler
logger = get_logger(__name__)
@asynccontextmanager
async def lifespan(app: FastAPI):
"""
Lifespan context manager for FastAPI app.
Handles startup and shutdown events.
"""
# Startup: Start the background scheduler
start_scheduler()
yield
# Shutdown: Stop the background scheduler
stop_scheduler()
def main():
separator = "=" * 60
# 0. Check Services (PostgreSQL & MinIO)
print(separator)
print("π§ Checking Services Status...\n")
try:
# Check MinIO
ensure_minio_running()
logger.info("MinIO service is running.")
# Check PostgreSQL
from backend.database.db_config import test_connection
success, msg = test_connection()
if success:
logger.info("PostgreSQL service is running.")
else:
raise Exception(f"PostgreSQL check failed: {msg}")
except Exception as e:
logger.error(f"Service check failed: {e}")
sys.exit(1)
print(separator + "\n")
# 1. Check Resources (Database & Bucket)
print(separator)
print("π Checking Resources Existence...\n")
try:
from backend.storage_service.minio_service import ensure_bucket_exists
from backend.database.db_config import ensure_database_exists
ensure_bucket_exists()
ensure_database_exists()
logger.info("Resources checked.")
except Exception as e:
logger.error(f"Resource check failed: {e}")
sys.exit(1)
print(separator + "\n")
# 2. Reset Database & Storage (if --reset)
if "--reset" in sys.argv:
print(separator)
print("π Resetting Database & Storage...\n")
try:
# Skip checks since we already performed them in Step 0
reset_database()
reset_minio()
logger.info("Database and storage reset complete.")
except Exception as e:
logger.error(f"Error resetting database: {e}")
sys.exit(1)
print(separator + "\n")
# 3. Set Default Data (if --set-default AND --reset)
if "--set-default" in sys.argv:
if "--reset" in sys.argv:
print(separator)
print("π₯ Inserting Default Data...\n")
try:
# No need to ensure_minio_running again as we checked in Step 0
set_default()
logger.info("Successfully inserted default data.")
except Exception as e:
logger.error(f"Error inserting default data: {e}")
sys.exit(1)
print(separator + "\n")
else:
logger.warning("Skipping --set-default: It requires --reset to be set.")
print(separator + "\n")
# 4. Initialize Application
print(separator)
print("π Initializing Application...\n")
try:
# Create FastAPI app
app = FastAPI(title="EduDataAggregator System API", lifespan=lifespan)
# CORS
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Include Routers
app.include_router(auth.router, prefix="/api/auth", tags=["Auth"])
app.include_router(dashboard.router, prefix="/api/dashboard", tags=["Dashboard"])
app.include_router(emails.router, prefix="/api/emails", tags=["Emails"])
app.include_router(tasks.router, prefix="/api/tasks", tags=["Tasks"])
app.include_router(teachers.router, prefix="/api/teachers", tags=["Teachers"])
app.include_router(templates.router, prefix="/api/templates", tags=["Templates"])
app.include_router(aggregations.router, prefix="/api/aggregations", tags=["Aggregations"])
app.include_router(settings.router, prefix="/api/settings", tags=["Settings"])
app.include_router(mailbox.router, prefix="/api/mailbox", tags=["Mailbox"])
app.include_router(files.router, prefix="/api/files", tags=["Files"])
app.include_router(agent.router, prefix="/api/agent", tags=["Agent"])
# Mount Frontend
frontend_path = os.path.join(os.path.dirname(__file__), "frontend")
if os.path.exists(frontend_path):
app.mount("/frontend", StaticFiles(directory=frontend_path, html=True), name="frontend")
@app.get("/")
async def root():
return RedirectResponse(url="/frontend/index.html")
else:
logger.warning("Frontend directory not found.")
logger.info("Application initialized successfully.")
except Exception as e:
logger.error(f"Application initialization failed: {e}")
sys.exit(1)
print(separator + "\n")
# 5. Run Server
print(separator)
print("π Starting server on http://localhost:8000\n")
uvicorn.run(app, host="0.0.0.0", port=8000)
print(separator + "\n")
if __name__ == "__main__":
main()