Profiling
Idea¶
Profiling is a technique to figure out how time is spent in a program. With these statistics, we can find the “hot spot” of a program and think about ways of improvement. Sometimes, a hot spot in an unexpected location may also hint at a bug in the program.
Pyinstrument is a Python profiler. A profiler is a tool to help you optimize your code - make it faster.
Profile a web request in FastAPI¶
To profile call stacks in FastAPI, you can write a middleware extension for
pyinstrument
.
Create an async function and decorate it with app.middleware('http')
where the
app is the name of your FastAPI application instance.
Make sure you configure a setting to only make this available when required.
from pyinstrument import Profiler
PROFILING = True # Set this from a settings model
if PROFILING:
@app.middleware("http")
async def profile_request(request: Request, call_next):
profiling = request.query_params.get("profile", False)
if profiling:
profiler = Profiler(interval=settings.profiling_interval, async_mode="enabled")
profiler.start()
await call_next(request)
profiler.stop()
return HTMLResponse(profiler.output_html())
else:
return await call_next(request)
To invoke, make any request to your application with the GET parameter
profile=1
and it will print the HTML result from pyinstrument
.
AuthX's Support¶
With AuthX the abstract of profiling is easy, it's just about calling the
ProfilerMiddleware
's class and calling it in
add_middleware(ProfilerMiddleware)
func that FastAPI provides.
Example¶
import os
import uvicorn
from fastapi import FastAPI
from fastapi.responses import JSONResponse
from authx import ProfilerMiddleware
app = FastAPI()
app.add_middleware(ProfilerMiddleware)
@app.get("/test")
async def normal_request():
return JSONResponse({"retMsg": "Hello World!"})
if __name__ == '__main__':
app_name = os.path.basename(__file__).replace(".py", "")
uvicorn.run(app=f"{app_name}:app", host="0.0.0.0", port=8080, workers=1)