Fred808 commited on
Commit
3d2a7d9
·
verified ·
1 Parent(s): 2f9734a

Upload main.py

Browse files
Files changed (1) hide show
  1. app/main.py +159 -163
app/main.py CHANGED
@@ -1,164 +1,160 @@
1
- from fastapi import FastAPI, Request, WebSocket
2
- from fastapi.middleware.cors import CORSMiddleware
3
- from fastapi.responses import RedirectResponse
4
- from app.core.config import settings
5
- from app.db.database import async_engine as engine, Base
6
- from app.api import auth, products, orders, users, analytics, files, notifications, calendar, scheduler, maintenance, branches, staff_analytics, sessions
7
- from app.utils.rate_limiter import rate_limiter
8
- from app.utils.logger import log_api_request
9
- from app.utils.tasks import run_periodic_tasks, sync_pos_metrics_task
10
- from app.services.websocket import connect, disconnect
11
- from app.realtime.subscriber import subscribe_order_events
12
- from app.routes.websocket import websocket_endpoint, manager, router as websocket_router, staff_metrics_websocket
13
- import socketio
14
- import time
15
- import logging
16
- import asyncio
17
- from typing import List, Dict, Optional
18
- from app.db.models import ensure_tables
19
-
20
- # Configure logging
21
- logging.basicConfig(level=logging.INFO)
22
- logger = logging.getLogger(__name__)
23
-
24
- # Create Socket.IO server
25
- sio = socketio.AsyncServer(async_mode='asgi', cors_allowed_origins='*')
26
- socket_app = socketio.ASGIApp(sio)
27
-
28
- app = FastAPI(title=settings.PROJECT_NAME, version=settings.VERSION, openapi_url=f"{settings.API_V1_STR}/openapi.json")
29
-
30
- # Store background tasks
31
- background_tasks = set()
32
-
33
- # Configure CORS
34
- app.add_middleware(
35
- CORSMiddleware,
36
- allow_origins=["http://localhost:5173", "http://localhost:3000"],
37
- allow_credentials=True,
38
- allow_methods=["*"],
39
- allow_headers=["*"],
40
- )
41
-
42
- # Socket.IO event handlers
43
- @sio.event
44
- async def connect(sid: str, environ: dict, auth: Optional[dict] = None):
45
- logger.info(f"Client connected: {sid}")
46
- return True
47
-
48
- @sio.event
49
- async def disconnect(sid: str):
50
- logger.info(f"Client disconnected: {sid}")
51
-
52
- @sio.event
53
- async def message(sid: str, data: dict):
54
- logger.info(f"Message from {sid}: {data}")
55
- await sio.emit('message', {'response': 'Message received'}, room=sid)
56
-
57
- # Mount Socket.IO app
58
- app.mount("/socket.io", socket_app)
59
-
60
- @app.get("/api/v1/health")
61
- async def health_check() -> Dict[str, str]:
62
- """Public health check endpoint that doesn't require authentication"""
63
- return {
64
- "status": "healthy",
65
- "version": settings.VERSION,
66
- "service": settings.PROJECT_NAME
67
- }
68
-
69
- # WebSocket endpoint
70
- @app.websocket("/ws")
71
- async def websocket_handler(websocket: WebSocket):
72
- await websocket_endpoint(websocket)
73
-
74
- @app.websocket("/ws/orders")
75
- async def orders_websocket_handler(websocket: WebSocket):
76
- await websocket_endpoint(websocket)
77
-
78
- # Request logging and rate limiting middleware
79
- @app.middleware("http")
80
- async def middleware(request: Request, call_next):
81
- await rate_limiter.check_rate_limit(request)
82
- start_time = time.time()
83
- response = await call_next(request)
84
- end_time = time.time()
85
- duration = end_time - start_time
86
- log_api_request(
87
- method=request.method,
88
- path=request.url.path,
89
- status_code=response.status_code,
90
- duration=duration
91
- )
92
- return response
93
-
94
- # Application startup and shutdown events
95
- @app.on_event("startup")
96
- async def startup_event():
97
- # Create all database tables
98
- async with engine.begin() as conn:
99
- await conn.run_sync(Base.metadata.create_all)
100
-
101
- # Ensure database tables exist
102
- await ensure_tables()
103
-
104
- # Start Redis subscriber in background
105
- task = asyncio.create_task(subscribe_order_events(manager))
106
- background_tasks.add(task)
107
- task.add_done_callback(background_tasks.discard)
108
-
109
- # Start periodic tasks
110
- task = asyncio.create_task(run_periodic_tasks())
111
- background_tasks.add(task)
112
- task.add_done_callback(background_tasks.discard)
113
-
114
- # Start POS metrics sync task
115
- task = asyncio.create_task(sync_pos_metrics_task())
116
- background_tasks.add(task)
117
- task.add_done_callback(background_tasks.discard)
118
-
119
- @app.on_event("shutdown")
120
- async def shutdown_event():
121
- # Cancel background tasks
122
- for task in background_tasks:
123
- task.cancel()
124
-
125
- # Dashboard compatibility routes
126
- @app.get(f"{settings.API_V1_STR}/sales")
127
- async def sales_redirect():
128
- return RedirectResponse(url=f"{settings.API_V1_STR}/analytics/sales")
129
-
130
- @app.get(f"{settings.API_V1_STR}/customers")
131
- async def customers_redirect():
132
- return RedirectResponse(url=f"{settings.API_V1_STR}/analytics/customers")
133
-
134
- @app.get(f"{settings.API_V1_STR}/brands")
135
- async def brands_redirect():
136
- return RedirectResponse(url=f"{settings.API_V1_STR}/analytics/brands")
137
-
138
- @app.get(f"{settings.API_V1_STR}/products")
139
- async def products_redirect():
140
- return RedirectResponse(url=f"{settings.API_V1_STR}/analytics/products")
141
-
142
- # Include routers
143
- app.include_router(auth.router, prefix=f"{settings.API_V1_STR}/auth", tags=["auth"])
144
- app.include_router(users.router, prefix=f"{settings.API_V1_STR}/users", tags=["users"])
145
- app.include_router(products.router, prefix=f"{settings.API_V1_STR}/products", tags=["products"])
146
- app.include_router(orders.router, prefix=f"{settings.API_V1_STR}/orders", tags=["orders"])
147
- app.include_router(analytics.router, prefix=f"{settings.API_V1_STR}/analytics", tags=["analytics"])
148
- app.include_router(files.router, prefix=f"{settings.API_V1_STR}/files", tags=["files"])
149
- app.include_router(notifications.router, prefix=f"{settings.API_V1_STR}/notifications", tags=["notifications"])
150
- app.include_router(calendar.router, prefix=f"{settings.API_V1_STR}/calendar", tags=["calendar"])
151
- app.include_router(scheduler.router, prefix=f"{settings.API_V1_STR}/scheduler", tags=["scheduler"])
152
- app.include_router(maintenance.router, prefix=f"{settings.API_V1_STR}/maintenance", tags=["maintenance"])
153
- app.include_router(branches.router, prefix=f"{settings.API_V1_STR}/branches", tags=["branches"])
154
- app.include_router(staff_analytics.router, prefix=f"{settings.API_V1_STR}/staff", tags=["staff"])
155
- app.include_router(sessions.router, prefix=f"{settings.API_V1_STR}/sessions", tags=["sessions"])
156
- app.include_router(websocket_router)
157
-
158
- @app.get("/")
159
- async def root():
160
- return {
161
- "message": f"Welcome to {settings.PROJECT_NAME} v{settings.VERSION}",
162
- "docs_url": "/docs",
163
- "openapi_url": "/openapi.json"
164
  }
 
1
+ from fastapi import FastAPI, Request, WebSocket
2
+ from fastapi.middleware.cors import CORSMiddleware
3
+ from fastapi.responses import RedirectResponse
4
+ from app.core.config import settings
5
+ from app.db.database import async_engine as engine, Base
6
+ from app.api import auth, products, orders, users, analytics, files, notifications, calendar, scheduler, maintenance, branches, staff_analytics, sessions
7
+ from app.utils.rate_limiter import rate_limiter
8
+ from app.utils.logger import log_api_request
9
+ from app.utils.tasks import run_periodic_tasks, sync_pos_metrics_task
10
+ from app.services.websocket import connect, disconnect
11
+ from app.realtime.subscriber import subscribe_order_events
12
+ from app.routes.websocket import websocket_endpoint, manager, router as websocket_router, staff_metrics_websocket
13
+ import socketio
14
+ import time
15
+ import logging
16
+ import asyncio
17
+ from typing import List, Dict, Optional
18
+ from app.db.models import ensure_tables
19
+
20
+ # Configure logging
21
+ logging.basicConfig(level=logging.INFO)
22
+ logger = logging.getLogger(__name__)
23
+
24
+ # Create Socket.IO server
25
+ sio = socketio.AsyncServer(async_mode='asgi', cors_allowed_origins='*')
26
+ socket_app = socketio.ASGIApp(sio)
27
+
28
+ app = FastAPI(title=settings.PROJECT_NAME, version=settings.VERSION, openapi_url=f"{settings.API_V1_STR}/openapi.json")
29
+
30
+ # Store background tasks
31
+ background_tasks = set()
32
+
33
+ # Configure CORS
34
+ app.add_middleware(
35
+ CORSMiddleware,
36
+ allow_origins=["http://localhost:5173", "http://localhost:3000"],
37
+ allow_credentials=True,
38
+ allow_methods=["*"],
39
+ allow_headers=["*"],
40
+ )
41
+
42
+ # Socket.IO event handlers
43
+ @sio.event
44
+ async def connect(sid: str, environ: dict, auth: Optional[dict] = None):
45
+ logger.info(f"Client connected: {sid}")
46
+ return True
47
+
48
+ @sio.event
49
+ async def disconnect(sid: str):
50
+ logger.info(f"Client disconnected: {sid}")
51
+
52
+ @sio.event
53
+ async def message(sid: str, data: dict):
54
+ logger.info(f"Message from {sid}: {data}")
55
+ await sio.emit('message', {'response': 'Message received'}, room=sid)
56
+
57
+ # Mount Socket.IO app
58
+ app.mount("/socket.io", socket_app)
59
+
60
+ @app.get("/api/v1/health")
61
+ async def health_check() -> Dict[str, str]:
62
+ """Public health check endpoint that doesn't require authentication"""
63
+ return {
64
+ "status": "healthy",
65
+ "version": settings.VERSION,
66
+ "service": settings.PROJECT_NAME
67
+ }
68
+
69
+ # WebSocket endpoint
70
+ @app.websocket("/ws")
71
+ async def websocket_handler(websocket: WebSocket):
72
+ await websocket_endpoint(websocket)
73
+
74
+ @app.websocket("/ws/orders")
75
+ async def orders_websocket_handler(websocket: WebSocket):
76
+ await websocket_endpoint(websocket)
77
+
78
+ # Request logging and rate limiting middleware
79
+ @app.middleware("http")
80
+ async def middleware(request: Request, call_next):
81
+ await rate_limiter.check_rate_limit(request)
82
+ start_time = time.time()
83
+ response = await call_next(request)
84
+ end_time = time.time()
85
+ duration = end_time - start_time
86
+ log_api_request(
87
+ method=request.method,
88
+ path=request.url.path,
89
+ status_code=response.status_code,
90
+ duration=duration
91
+ )
92
+ return response
93
+
94
+ # Application startup and shutdown events
95
+ @app.on_event("startup")
96
+ async def startup_event():
97
+ # Create all database tables
98
+ await ensure_tables()
99
+
100
+ # Start Redis subscriber in background
101
+ task = asyncio.create_task(subscribe_order_events(manager))
102
+ background_tasks.add(task)
103
+ task.add_done_callback(background_tasks.discard)
104
+
105
+ # Start periodic tasks
106
+ task = asyncio.create_task(run_periodic_tasks())
107
+ background_tasks.add(task)
108
+ task.add_done_callback(background_tasks.discard)
109
+
110
+ # Start POS metrics sync task
111
+ task = asyncio.create_task(sync_pos_metrics_task())
112
+ background_tasks.add(task)
113
+ task.add_done_callback(background_tasks.discard)
114
+
115
+ @app.on_event("shutdown")
116
+ async def shutdown_event():
117
+ # Cancel background tasks
118
+ for task in background_tasks:
119
+ task.cancel()
120
+
121
+ # Dashboard compatibility routes
122
+ @app.get(f"{settings.API_V1_STR}/sales")
123
+ async def sales_redirect():
124
+ return RedirectResponse(url=f"{settings.API_V1_STR}/analytics/sales")
125
+
126
+ @app.get(f"{settings.API_V1_STR}/customers")
127
+ async def customers_redirect():
128
+ return RedirectResponse(url=f"{settings.API_V1_STR}/analytics/customers")
129
+
130
+ @app.get(f"{settings.API_V1_STR}/brands")
131
+ async def brands_redirect():
132
+ return RedirectResponse(url=f"{settings.API_V1_STR}/analytics/brands")
133
+
134
+ @app.get(f"{settings.API_V1_STR}/products")
135
+ async def products_redirect():
136
+ return RedirectResponse(url=f"{settings.API_V1_STR}/analytics/products")
137
+
138
+ # Include routers
139
+ app.include_router(auth.router, prefix=f"{settings.API_V1_STR}/auth", tags=["auth"])
140
+ app.include_router(users.router, prefix=f"{settings.API_V1_STR}/users", tags=["users"])
141
+ app.include_router(products.router, prefix=f"{settings.API_V1_STR}/products", tags=["products"])
142
+ app.include_router(orders.router, prefix=f"{settings.API_V1_STR}/orders", tags=["orders"])
143
+ app.include_router(analytics.router, prefix=f"{settings.API_V1_STR}/analytics", tags=["analytics"])
144
+ app.include_router(files.router, prefix=f"{settings.API_V1_STR}/files", tags=["files"])
145
+ app.include_router(notifications.router, prefix=f"{settings.API_V1_STR}/notifications", tags=["notifications"])
146
+ app.include_router(calendar.router, prefix=f"{settings.API_V1_STR}/calendar", tags=["calendar"])
147
+ app.include_router(scheduler.router, prefix=f"{settings.API_V1_STR}/scheduler", tags=["scheduler"])
148
+ app.include_router(maintenance.router, prefix=f"{settings.API_V1_STR}/maintenance", tags=["maintenance"])
149
+ app.include_router(branches.router, prefix=f"{settings.API_V1_STR}/branches", tags=["branches"])
150
+ app.include_router(staff_analytics.router, prefix=f"{settings.API_V1_STR}/staff", tags=["staff"])
151
+ app.include_router(sessions.router, prefix=f"{settings.API_V1_STR}/sessions", tags=["sessions"])
152
+ app.include_router(websocket_router)
153
+
154
+ @app.get("/")
155
+ async def root():
156
+ return {
157
+ "message": f"Welcome to {settings.PROJECT_NAME} v{settings.VERSION}",
158
+ "docs_url": "/docs",
159
+ "openapi_url": "/openapi.json"
 
 
 
 
160
  }