-
Notifications
You must be signed in to change notification settings - Fork 6
/
main.py
104 lines (88 loc) · 2.96 KB
/
main.py
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
import logging
import asyncio
import uvicorn
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.exceptions import RequestValidationError
from fastapi.routing import APIRoute
from utils.log import logger
from fastapi.exception_handlers import (
http_exception_handler,
request_validation_exception_handler,
)
from contextlib import asynccontextmanager
from jobs import stop_scheduler, start_scheduler
from routers import subscription
from fastapi_responses import custom_openapi
from starlette.exceptions import HTTPException as StarletteHTTPException
from utils.config import (
UVICORN_HOST,
UVICORN_PORT,
UVICORN_UDS,
UVICORN_SSL_CERTFILE,
UVICORN_SSL_KEYFILE,
DOCS,
)
__version__ = "0.1.0"
@asynccontextmanager
async def lifespan(app: FastAPI):
"""Manage application startup and shutdown events."""
await start_scheduler()
logger.info("Application started successfully.")
yield # App will be running during this period
await stop_scheduler()
logger.info("Application shut down successfully.")
def create_app() -> FastAPI:
"""Create and configure FastAPI application instance."""
app = FastAPI(
title="Migration",
description="API to proxy subscription requests between users and backend system",
version=__version__,
docs_url="/docs" if DOCS else None,
redoc_url="/redoc" if DOCS else None,
lifespan=lifespan, # Set the lifespan context manager
)
app.openapi = custom_openapi(app)
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
@app.exception_handler(StarletteHTTPException)
async def custom_http_exception_handler(request, exc):
logger.error(f"An HTTP error!: {repr(exc)}")
return await http_exception_handler(request, exc)
@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request, exc):
logger.error(f"The client sent invalid data!: {exc}")
return await request_validation_exception_handler(request, exc)
for route in app.routes:
if isinstance(route, APIRoute):
route.operation_id = route.name
# Include the router
app.include_router(subscription.router)
return app
async def main():
"""Main function to run the application."""
app = create_app()
config = uvicorn.Config(
app,
host=UVICORN_HOST,
port=UVICORN_PORT,
uds=UVICORN_UDS,
ssl_certfile=UVICORN_SSL_CERTFILE,
ssl_keyfile=UVICORN_SSL_KEYFILE,
workers=1,
log_level=logging.INFO,
)
server = uvicorn.Server(config)
await server.serve()
if __name__ == "__main__":
try:
asyncio.run(main())
except FileNotFoundError as e:
logger.error(f"FileNotFoundError: {e}")
except Exception as e:
logger.error(f"An error occurred: {e}")