113 lines
3.0 KiB
Python
113 lines
3.0 KiB
Python
import pathlib
|
|
from functools import lru_cache
|
|
|
|
import toml
|
|
from fastapi import FastAPI
|
|
from fastapi.encoders import jsonable_encoder
|
|
from fastapi.exceptions import RequestValidationError
|
|
from fastapi.openapi.docs import get_redoc_html
|
|
from fastapi.openapi.utils import get_openapi
|
|
from fastapi.staticfiles import StaticFiles
|
|
from starlette import status
|
|
from starlette.middleware.cors import CORSMiddleware
|
|
from starlette.responses import JSONResponse
|
|
|
|
from config import conf
|
|
from core.app.context import useAppContext
|
|
from core.app.docs import get_spotlight_docs
|
|
|
|
app = FastAPI(debug=True, root_path=conf.server.base_api_doc_url)
|
|
|
|
app.state = useAppContext()
|
|
|
|
# mount and map static directory
|
|
|
|
for _route, _dir in conf.static_files.items():
|
|
app.mount(f'{conf.server.prefix_url}/{_route}',
|
|
StaticFiles(directory=_dir), name=_dir)
|
|
|
|
|
|
def _parse_toml(pyproject_path):
|
|
pyproject_text = pyproject_path.read_text()
|
|
pyproject_data = toml.loads(pyproject_text)
|
|
info = pyproject_data['tool']['poetry']
|
|
setup_data = {
|
|
'name': info.get('name', 'No Name'),
|
|
'version': info.get('version', 'No version'),
|
|
'description': info.get('description', 'No description'),
|
|
'authors': info.get('authors', ['None']),
|
|
}
|
|
return setup_data
|
|
|
|
|
|
def get_pkg_info():
|
|
pyproject_path = pathlib.Path('pyproject.toml')
|
|
return _parse_toml(pyproject_path)
|
|
|
|
|
|
@app.exception_handler(RequestValidationError)
|
|
async def validation_exception_handler(request, exc: RequestValidationError):
|
|
return JSONResponse(
|
|
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
|
content=jsonable_encoder({"data": exc.errors(), "message": 'Validation error', 'code': 422}),
|
|
)
|
|
|
|
|
|
@app.get('/ping')
|
|
def ping():
|
|
return {"message": "pong", 'api_version': 2, "production": conf.server.is_prod, **get_pkg_info()}
|
|
|
|
|
|
def custom_openapi():
|
|
if app.openapi_schema:
|
|
return app.openapi_schema
|
|
info = get_pkg_info()
|
|
openapi_schema = get_openapi(
|
|
title=f'{info.get("name")} Api Documents',
|
|
version=info.get("version"),
|
|
description=info.get("description"),
|
|
routes=app.routes,
|
|
)
|
|
openapi_schema["info"]["x-logo"] = {
|
|
"url": conf.server.api_logo
|
|
}
|
|
app.openapi_schema = openapi_schema
|
|
return app.openapi_schema
|
|
|
|
|
|
@app.get("/redoc", include_in_schema=False)
|
|
async def redoc_html():
|
|
info = get_pkg_info()
|
|
return get_redoc_html(
|
|
openapi_url=app.openapi_url,
|
|
title=info.get('name') + " - ReDoc",
|
|
)
|
|
|
|
|
|
@app.get("/docu", include_in_schema=False)
|
|
async def docu():
|
|
info = get_pkg_info()
|
|
return get_spotlight_docs(
|
|
openapi_url=app.openapi_url,
|
|
title=info.get('name') + " - Docu",
|
|
)
|
|
|
|
|
|
app.openapi = custom_openapi
|
|
|
|
|
|
@lru_cache()
|
|
def load_origins():
|
|
return conf.cors.origins or []
|
|
|
|
|
|
app.add_middleware(
|
|
CORSMiddleware,
|
|
allow_origins=load_origins(),
|
|
allow_credentials=conf.cors.allow_credentials,
|
|
allow_methods=conf.cors.allow_methods,
|
|
allow_headers=conf.cors.allow_headers,
|
|
)
|
|
|
|
app.router.redirect_slashes = False
|