mirror of
https://github.com/grillazz/fastapi-sqlalchemy-asyncpg.git
synced 2026-03-06 10:00:39 +03:00
feat: add profiling middleware and update README for performance profiling
This commit is contained in:
@@ -13,7 +13,12 @@ router = APIRouter()
|
||||
|
||||
|
||||
@router.get("/redis", status_code=status.HTTP_200_OK)
|
||||
async def redis_check(request: Request):
|
||||
async def redis_check(
|
||||
request: Request,
|
||||
pyprofile: Annotated[
|
||||
bool, Query(description="Enable profiler for this request")
|
||||
] = False,
|
||||
):
|
||||
"""
|
||||
Endpoint to check Redis health and retrieve server information.
|
||||
|
||||
@@ -23,6 +28,7 @@ async def redis_check(request: Request):
|
||||
|
||||
Args:
|
||||
request (Request): The incoming HTTP request.
|
||||
pyprofile (bool, optional): If `True`, enables the profiler for this request. Defaults to `False`.
|
||||
|
||||
Returns:
|
||||
dict or None: Returns Redis server information as a dictionary if successful,
|
||||
|
||||
12
app/main.py
12
app/main.py
@@ -6,6 +6,8 @@ from fastapi import Depends, FastAPI, Request
|
||||
from fastapi.responses import HTMLResponse
|
||||
from fastapi.templating import Jinja2Templates
|
||||
from rotoger import get_logger
|
||||
from starlette.middleware import Middleware
|
||||
from starlette.middleware.gzip import GZipMiddleware
|
||||
|
||||
from app.api.health import router as health_router
|
||||
from app.api.ml import router as ml_router
|
||||
@@ -15,6 +17,7 @@ from app.api.stuff import router as stuff_router
|
||||
from app.api.user import router as user_router
|
||||
from app.config import settings as global_settings
|
||||
from app.exception_handlers import register_exception_handlers
|
||||
from app.middleware.profiler import ProfilingMiddleware
|
||||
from app.redis import get_redis
|
||||
from app.services.auth import AuthBearer
|
||||
|
||||
@@ -44,11 +47,18 @@ async def lifespan(app: FastAPI):
|
||||
await app.postgres_pool.close()
|
||||
|
||||
|
||||
middleware = [
|
||||
Middleware(GZipMiddleware),
|
||||
Middleware(ProfilingMiddleware),
|
||||
]
|
||||
|
||||
|
||||
def create_app() -> FastAPI:
|
||||
app = FastAPI(
|
||||
title="Stuff And Nonsense API",
|
||||
version="1.22.0",
|
||||
lifespan=lifespan,
|
||||
middleware=middleware,
|
||||
)
|
||||
app.include_router(stuff_router)
|
||||
app.include_router(nonsense_router)
|
||||
@@ -68,6 +78,8 @@ def create_app() -> FastAPI:
|
||||
# Register exception handlers
|
||||
register_exception_handlers(app)
|
||||
|
||||
|
||||
|
||||
@app.get("/index", response_class=HTMLResponse)
|
||||
def get_index(request: Request):
|
||||
return templates.TemplateResponse("index.html", {"request": request})
|
||||
|
||||
0
app/middleware/__init__.py
Normal file
0
app/middleware/__init__.py
Normal file
28
app/middleware/profiler.py
Normal file
28
app/middleware/profiler.py
Normal file
@@ -0,0 +1,28 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from fastapi import Request
|
||||
from pyinstrument import Profiler
|
||||
from starlette.middleware.base import (
|
||||
BaseHTTPMiddleware,
|
||||
RequestResponseEndpoint,
|
||||
)
|
||||
from starlette.responses import HTMLResponse, Response
|
||||
|
||||
|
||||
class ProfilingMiddleware(BaseHTTPMiddleware):
|
||||
async def dispatch(
|
||||
self, request: Request, call_next: RequestResponseEndpoint
|
||||
) -> Response:
|
||||
if request.query_params.get("pyprofile") == "true":
|
||||
profiler = Profiler(interval=0.001, async_mode="enabled")
|
||||
profiler.start()
|
||||
|
||||
await call_next(request)
|
||||
|
||||
profiler.stop()
|
||||
return HTMLResponse(
|
||||
profiler.output_html(),
|
||||
headers={"Content-Disposition": "attachment; filename=profile.html"},
|
||||
)
|
||||
|
||||
return await call_next(request)
|
||||
Reference in New Issue
Block a user