Spaces:
Sleeping
Sleeping
| import asyncio | |
| import logging | |
| from fastapi import FastAPI, Request | |
| from fastapi.middleware.cors import CORSMiddleware | |
| from fastapi.responses import JSONResponse | |
| from fastapi.exceptions import RequestValidationError, HTTPException | |
| from starlette.status import HTTP_400_BAD_REQUEST | |
| from App.routers.stocks.routes import router as stocks_router | |
| from App.routers.funds.routes import router as funds_router | |
| from App.routers.bonds.routes import router as bonds_router | |
| from App.routers.tasks.routes import router as tasks_router | |
| from App.routers.users.routes import router as users_router | |
| from App.routers.portfolio.routes import router as portfolio_router | |
| from App.routers.admin.routes import router as admin_router | |
| from App.routers.economy.config import load_local_env | |
| from App.routers.economy.routes import api_router as economy_api_router, router as economy_router | |
| from uvicorn.middleware.proxy_headers import ProxyHeadersMiddleware | |
| from App.schemas import ResponseModel, AppException | |
| from App.scheduler import scheduled_economy_loop, scheduled_market_loop, scheduled_news_loop | |
| from db import init_db, close_db, clear_db | |
| logging.basicConfig( | |
| level=logging.INFO, | |
| format="%(asctime)s %(levelname)s %(name)s: %(message)s", | |
| ) | |
| logger = logging.getLogger(__name__) | |
| load_local_env() | |
| app = FastAPI( | |
| title="Uwekezaji API", description="Stock Market Data API", redirect_slashes=False | |
| ) | |
| def _json_safe(value): | |
| if isinstance(value, bytes): | |
| return value.decode("utf-8", errors="replace") | |
| if isinstance(value, dict): | |
| return {key: _json_safe(item) for key, item in value.items()} | |
| if isinstance(value, list): | |
| return [_json_safe(item) for item in value] | |
| if isinstance(value, tuple): | |
| return [_json_safe(item) for item in value] | |
| return value | |
| async def custom_http_exception_handler(request: Request, exc: AppException): | |
| return JSONResponse( | |
| status_code=exc.status_code, | |
| content=ResponseModel( | |
| success=False, | |
| message=getattr(exc, "message", str(exc.detail)), | |
| data=getattr(exc, "data", None), | |
| ).model_dump(), | |
| ) | |
| async def generic_http_exception_handler(request: Request, exc: HTTPException): | |
| return JSONResponse( | |
| status_code=exc.status_code, | |
| content=ResponseModel( | |
| success=False, | |
| message=str(exc.detail), | |
| data=None, | |
| ).model_dump(), | |
| ) | |
| async def validation_exception_handler(request: Request, exc: RequestValidationError): | |
| return JSONResponse( | |
| status_code=HTTP_400_BAD_REQUEST, | |
| content=ResponseModel( | |
| success=False, | |
| message="Validation error", | |
| data={"errors": _json_safe(exc.errors())}, | |
| ).model_dump(), | |
| ) | |
| app.add_middleware( | |
| CORSMiddleware, | |
| allow_origins=["*"], | |
| allow_credentials=False, | |
| allow_methods=["*"], | |
| allow_headers=["*"], | |
| ) | |
| app.include_router(stocks_router) | |
| app.include_router(funds_router) | |
| app.include_router(bonds_router) | |
| app.include_router(tasks_router) | |
| app.include_router(users_router) | |
| app.include_router(portfolio_router) | |
| app.include_router(admin_router) | |
| app.include_router(economy_router) | |
| app.include_router(economy_api_router) | |
| app.add_middleware(ProxyHeadersMiddleware, trusted_hosts="*") | |
| async def startup_event(): | |
| logger.info("[startup] database initialization started") | |
| await init_db() | |
| logger.info("[startup] database initialization complete") | |
| asyncio.create_task(scheduled_market_loop()) | |
| logger.info("[startup] scheduled market background loop started") | |
| asyncio.create_task(scheduled_news_loop()) | |
| logger.info("[startup] scheduled news background loop started") | |
| asyncio.create_task(scheduled_economy_loop()) | |
| logger.info("[startup] economy pipeline loop registered") | |
| async def shutdown_event(): | |
| await close_db() | |
| async def root(): | |
| return {"message": "Welcome to Uwekezaji API"} | |