A fully modernized fork of the original flask-profiler project. It delivers the profiling simplicity you expect with a refreshed UI, secure defaults, first-class support for Flask 3.x, and seamless reuse of your existing flask-login or flask-security setup. Modernization and ongoing maintenance are led by Berk Polat, building on the foundation created by Mustafa Atik.
- Features
- Installation
- Quick Start
- Instrumentation Model
- Dashboard Tour
- Storage Backends
- Configuration Cheat Sheet
- Sampling & Filtering
- API Endpoints
- Development
- Contributing
- Credits & License
- Flask 3.x compatible – Extension-style initialization with per-app state and thread safety.
- Modern dashboard – Vite-built UI, responsive layout, and syntax-highlighted measurement detail.
- Multi-backend storage – SQLite, SQLAlchemy, and MongoDB (or custom engines) with parametrized pytest coverage.
- Drop-in authentication – Ship with built-in basic auth or reuse the
flask-login/flask-securityprotection already in your app. - Secure defaults – Ignore patterns, highlighted configuration guidance, and headers that keep the dashboard private.
- Simple integration – One
init_appcall profiles existing routes; decorators cover factory or late-registered endpoints.
pip install flask-profiler-modernOptional extras bring in backend-specific dependencies:
| Extra | Command | Includes |
|---|---|---|
| SQLAlchemy storage | pip install flask-profiler-modern[sqlalchemy] |
SQLAlchemy>=2.0.0 |
| MongoDB storage | pip install flask-profiler-modern[mongo] |
pymongo>=4.14.1,<5 |
| Everything | pip install flask-profiler-modern[all] |
Both of the above |
from flask import Flask
import flask_profiler
app = Flask(__name__)
app.config["DEBUG"] = True
app.config["flask_profiler"] = {
"enabled": True,
"storage": {
"engine": "sqlite", # sqlite | sqlalchemy | mongodb | dotted path
"db_url": "sqlite:///profiler.db"
},
"basicAuth": {
"enabled": False # enable
},
"ignore": ["^/static/.*"]
}
@app.route("/ping")
def ping():
return "pong"
flask_profiler.init_app(app)
# Routes registered after init_app need explicit opt-in.
@app.route("/late")
@flask_profiler.profile()
def late_route():
return "tracked"
if __name__ == "__main__":
app.run()Open http://127.0.0.1:5000/flask-profiler/ to view the dashboard.
| Scenario | How to profile it |
|---|---|
Routes defined before init_app |
Automatically wrapped when you call flask_profiler.init_app(app) |
Routes added after init_app |
Decorate with @flask_profiler.profile() |
| Factory/blueprint pattern | Call init_app inside your factory once routes are registered, or decorate the blueprint views |
| Custom instrumentation | Use flask_profiler.measure(func, name, method) to wrap arbitrary callables |
TIP:
flask_profiler.current_profilerexposes the active profiler state if you need low-level access.
- Overview – Request timeline & method distribution with range controls.
- Filtering – Server-side table with sort/search plus quick filters from the dashboard.
- Details – Syntax-highlighted JSON modal enumerating request context, headers, args, and body.
Configuration lives under app.config["flask_profiler"]["storage"].
| Engine | Minimal config | Notes |
|---|---|---|
| SQLite | { "engine": "sqlite", "db_url": "sqlite:///profiler.db" } |
Default if omitted |
| SQLAlchemy | { "engine": "sqlalchemy", "db_url": "postgresql://..." } |
Works with any SQLAlchemy URL |
| MongoDB | { "engine": "mongodb", "MONGO_URL": "mongodb://..." } |
Requires pymongo (or mongomock for tests) |
| Custom class | { "engine": "package.module.CustomStorage" } |
Must subclass flask_profiler.storage.BaseStorage |
Extras control dependency installation; see Installation.
| Key | Type | Default | Description |
|---|---|---|---|
enabled |
bool | False |
Toggle profiling globally |
storage.engine |
str | "sqlite" |
Storage backend identifier |
storage.db_url |
str | engine-specific | Optional database URL for SQL storage |
basicAuth.enabled |
bool | False |
Enable dashboard authentication |
basicAuth.username/password |
str | admin/admin (example) |
Credentials if basic auth is enabled |
ignore |
list[str] | [] |
Regex patterns to skip profiling |
sampling_function |
callable | None |
Return truthy to record, falsy to skip |
endpointRoot |
str | "flask-profiler" |
URL prefix for dashboard and API |
verbose |
bool | False |
Print measurement JSON to stdout |
flask-profiler keeps the dashboard private with built-in HTTP basic auth. Provide basicAuth.enabled, basicAuth.username, and basicAuth.password to require credentials; otherwise the dashboard remains unsecured.
Use a callable to decide per-request whether to record data.
import random
app.config["flask_profiler"] = {
"sampling_function": lambda: random.random() < 0.05 # 5% sample rate
}app.config["flask_profiler"] = {
"ignore": [
"^/static/.*",
"/healthz",
"/metrics"
]
}Ignored routes and unsuccessful samples are never written to storage.
The dashboard uses a small JSON API rooted at /flask-profiler/ by default. You can call these directly:
| Endpoint | Method | Description |
|---|---|---|
/flask-profiler/api/measurements/ |
GET | Paged measurements (supports filters) |
/flask-profiler/api/measurements/grouped |
GET | Aggregated per endpoint statistics |
/flask-profiler/api/measurements/<id> |
GET | Full measurement payload |
/flask-profiler/api/measurements/timeseries/ |
GET | Request counts over time |
/flask-profiler/api/measurements/methodDistribution/ |
GET | Count of requests per HTTP method |
/flask-profiler/db/dumpDatabase |
GET | Download all measurements as JSON |
/flask-profiler/db/deleteDatabase |
GET | Delete all stored measurements |
Parameters such as startedAt, endedAt, skip, limit, and sort mirror those used by the UI. All endpoints require basic auth if you enable it.
Clone the repo and set up your environment:
git clone https://github.com/berkpolatCE/flask-profiler-modern.git
cd flask-profiler-modern
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
cd flask_profiler/static
npm install
npm run devRun tests before submitting changes:
source .venv/bin/activate
pytestBuilding frontend assets:
cd flask_profiler/static
npm run buildFLASK_PROFILER_TEST_MONGO_URI points pytest at a real MongoDB. Without it, tests fall back to mongomock.
Contributions are welcome! Please read CONTRIBUTING.md for the contributor workflow, coding standards, and test requirements. Open issues and roadmap items live at github.com/berkpolatCE/flask-profiler-modern/issues.
- Original author: Mustafa Atik — github.com/muatik/flask-profiler
- Modernization & maintenance: Berk Polat
- Licensed under the MIT License
If this project helps you, please star the repository or share your improvements with the community!


