92 lines
2.8 KiB
Python
92 lines
2.8 KiB
Python
# -*- coding = utf-8 -*-
|
|
# @Time : 2025/2/13 下午12:27
|
|
# @File : app.py
|
|
# @Software : PyCharm
|
|
# @Author : xingc
|
|
# @Desc :
|
|
import logging
|
|
|
|
import redis.asyncio as aioredis
|
|
from fastapi import FastAPI, Request, Response, status
|
|
from fastapi.responses import UJSONResponse
|
|
from fastapi.exceptions import HTTPException, RequestValidationError
|
|
from fastapi_limiter import FastAPILimiter
|
|
|
|
from config import settings
|
|
from core.db.engine import get_cache
|
|
from core.routers.route import routers
|
|
from core.routers.chat.handlers import socket_manager
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
async def exception_log(request: Request, exc):
|
|
logger.error('\n'.join([
|
|
'',
|
|
f'request method: {request.method}',
|
|
f'request path: {request.path_params}',
|
|
f'request host: {request.client.host}',
|
|
f'query parameters: {dict(request.query_params)}',
|
|
f'abnormal description: {exc}',
|
|
]))
|
|
logger.exception(exc)
|
|
|
|
|
|
def create_app() -> FastAPI:
|
|
app = FastAPI(
|
|
debug=settings.DEBUG,
|
|
openapi_url='/openapi.json' if settings.DEBUG else None
|
|
)
|
|
|
|
for router in routers:
|
|
app.include_router(router)
|
|
|
|
@app.on_event('startup')
|
|
async def startup_event():
|
|
redis_conn = await get_cache()
|
|
await FastAPILimiter.init(redis_conn)
|
|
logger.info(f'Application ``{settings.NAME}`` is started')
|
|
|
|
@app.on_event('shutdown')
|
|
async def shutdown_event():
|
|
logger.info(f'Application ``{settings.NAME}`` is closed')
|
|
await socket_manager.pubsub_client.disconnect()
|
|
|
|
@app.exception_handler(HTTPException)
|
|
async def http_exception_handler(request: Request, exc: HTTPException):
|
|
await exception_log(request, exc)
|
|
return UJSONResponse(
|
|
status_code=exc.status_code,
|
|
content={
|
|
'status': exc.status_code,
|
|
'data': None,
|
|
'message': exc.detail
|
|
}
|
|
)
|
|
|
|
@app.exception_handler(RequestValidationError)
|
|
async def http_exception_handler(request: Request, exc: RequestValidationError):
|
|
await exception_log(request, exc)
|
|
return UJSONResponse(
|
|
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
|
content={
|
|
'status': status.HTTP_422_UNPROCESSABLE_ENTITY,
|
|
'data': exc.errors(),
|
|
'message': 'Validation error'
|
|
}
|
|
)
|
|
|
|
@app.exception_handler(Exception)
|
|
async def http_exception_handler(request: Request, exc: Exception):
|
|
await exception_log(request, exc)
|
|
return UJSONResponse(
|
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
content={
|
|
'status': status.HTTP_500_INTERNAL_SERVER_ERROR,
|
|
'data': None,
|
|
'message': 'Internal server error'
|
|
}
|
|
)
|
|
|
|
return app
|