Skip to main content

A developer debug toolbar for FastAPI — inspect SQL, requests, performance, logs, and cache in real time.

Project description

FastPanel

PyPI version Tests Coverage License: MIT Python 3.11+

A developer debug toolbar for FastAPI — see every SQL query, request detail, log record, and cache operation in a floating in-browser panel, with zero code changes to your routes.

Inspired by django-debug-toolbar, built for the modern async FastAPI stack.


Features

Panel What it shows
SQL Every SQLAlchemy query: timing, formatted SQL, slow query highlighting (>100ms), calling location
Request Method, URL, path/query params, headers, cookies, JSON body
Response Status code, headers, content type, size
Performance Total wall time, CPU time, panel overhead
Logging All Python logging records at WARNING+ during the request
Cache Hit/miss/set/delete events, hit rate, per-operation log
Headers Full request and response header tables
  • Zero overhead in production (enabled=False is a pure pass-through)
  • Two-line mount — no route decorators, no config files
  • Async-native — works with asyncio, asyncpg, aiosqlite
  • Pluggable custom panels via AbstractPanel
  • No frontend build step — vanilla HTML/CSS/JS

Installation

pip install fastpanel

# With SQLAlchemy support (SQL panel):
pip install fastpanel[sqlalchemy]

# With Redis support (Cache panel):
pip install fastpanel[redis]

# Everything:
pip install fastpanel[all]

Or with Poetry:

poetry add fastpanel
poetry add fastpanel[sqlalchemy]

Quickstart

from fastapi import FastAPI
from fastpanel import FastPanel
import os

app = FastAPI()

# Your routes here...

# Mount FastPanel — two lines, that's it.
FastPanel(app, enabled=os.getenv("ENVIRONMENT") == "development")

Start your app and visit any HTML page. The toolbar appears in the bottom-right corner.

Tip: Set the FASTPANEL_ENABLED=true environment variable instead of hardcoding enabled=True. That way it's impossible to accidentally enable it in production.


Configuration

All settings can be passed to the FastPanel constructor or set via environment variables (FASTPANEL_ prefix):

Setting Env var Default Description
enabled FASTPANEL_ENABLED False Master switch. Never True in production.
mount_path FASTPANEL_MOUNT_PATH /__fastpanel URL prefix for internal routes
store_max_requests FASTPANEL_STORE_MAX_REQUESTS 100 Max requests in memory (LRU)
show_sql FASTPANEL_SHOW_SQL True Enable SQL panel
show_logging FASTPANEL_SHOW_LOGGING True Enable Logging panel
show_cache FASTPANEL_SHOW_CACHE True Enable Cache panel
slow_query_ms FASTPANEL_SLOW_QUERY_MS 100.0 SQL query slow threshold (ms)
excluded_paths [] URL prefixes to skip (mount_path always excluded)
extra_panels [] Custom panel classes to append
FastPanel(
    app,
    enabled=True,
    slow_query_ms=50.0,
    store_max_requests=200,
    excluded_paths=["/health", "/metrics"],
)

Cache Panel — CacheTracker

The Cache panel requires wrapping your cache client:

from fastpanel.panels.cache import CacheTracker, InMemoryCache
import redis.asyncio

# In-memory cache (development/testing):
cache = CacheTracker(InMemoryCache())

# Redis (production-like):
raw_redis = redis.asyncio.Redis.from_url("redis://localhost")
cache = CacheTracker(raw_redis)

# Use cache normally — all operations are tracked:
await cache.set("user:1", user_data)
value = await cache.get("user:1")   # recorded as a hit
await cache.delete("user:1")

SQLAlchemy Integration

The SQL panel hooks into SQLAlchemy's global event system automatically — no changes needed to your engine or session setup. Works with:

  • AsyncEngine + AsyncSession (SQLAlchemy 2.x)
  • create_async_engine("sqlite+aiosqlite://...")
  • create_async_engine("postgresql+asyncpg://...")
  • Synchronous engines too

Note on async location tracking: With SQLAlchemy async engines, the query source location (app/models.py:42) may show <unknown>. This is because async SQLAlchemy uses greenlets to run sync drivers, and the async call stack isn't visible from within the cursor execute event. This is a known limitation. See DEVLOG.md Step 8 for details.


Writing a Custom Panel

Subclass AbstractPanel:

from fastpanel.panels.base import AbstractPanel
from starlette.requests import Request
from starlette.responses import Response
from typing import Any

class TimingPanel(AbstractPanel):
    panel_id = "timing"
    title = "Timing"

    def __init__(self) -> None:
        super().__init__()
        self._events: list[str] = []

    def reset(self) -> None:
        self._events = []

    async def process_request(self, request: Request) -> None:
        self._events.append(f"Request received: {request.url.path}")

    def get_stats(self) -> str:
        return str(len(self._events))

    def get_data(self) -> dict[str, Any]:
        return {"events": self._events}

Register it:

FastPanel(app, enabled=True, extra_panels=[TimingPanel])

⚠️ Security Warning

FastPanel must never be enabled in production.

The toolbar exposes internal request data (headers, SQL queries, log records) via the /__fastpanel/api/ endpoint. While the endpoint requires a UUID4 request_id (not guessable), it is still sensitive data that should never be exposed in a production environment.

Recommended pattern:

import os

FastPanel(
    app,
    enabled=os.getenv("ENVIRONMENT") == "development"
    # or:
    # enabled=os.getenv("FASTPANEL_ENABLED", "false").lower() == "true"
)

Ensure ENVIRONMENT=development (or FASTPANEL_ENABLED=true) is never set in your production environment or deployment configuration.

When enabled=False:

  • All /__fastpanel/ routes return 404 (not 403 — the 404 does not reveal that FastPanel is installed)
  • The middleware is a 4-line pass-through with zero overhead
  • No panel data is collected or stored

How This Was Built

See DEVLOG.md for the full step-by-step build narrative — from pyproject.toml to the final test run. Every design decision, architectural trade-off, and gotcha is documented.


Roadmap

  • WebSocket panel
  • Async log streaming (live panel updates)
  • Redis store backend (persist panel data across restarts)
  • Tortoise-ORM support
  • Browser extension version (persistent across sessions)
  • Profiler panel (line-level cProfile integration)
  • Template panel (Jinja2 render times)
  • Custom panel plugin registry

Contributing

See CONTRIBUTING.md for development setup, testing instructions, branch naming conventions, and the PR checklist.


License

MIT — © 2026 officialalkenes

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fastpanel-0.1.0.tar.gz (37.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fastpanel-0.1.0-py3-none-any.whl (46.5 kB view details)

Uploaded Python 3

File details

Details for the file fastpanel-0.1.0.tar.gz.

File metadata

  • Download URL: fastpanel-0.1.0.tar.gz
  • Upload date:
  • Size: 37.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.9

File hashes

Hashes for fastpanel-0.1.0.tar.gz
Algorithm Hash digest
SHA256 5aff9a40e652427994082076f70a703c59d6f615a7c86f798577385fdd50447d
MD5 b8c70d82aa0452a2f153b119cac1cf9f
BLAKE2b-256 552724f557241f9af0364e7f8d30a82ab157a2aeaec26237dd96c08227a9639a

See more details on using hashes here.

File details

Details for the file fastpanel-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: fastpanel-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 46.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.9

File hashes

Hashes for fastpanel-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 dcf7c82d5ccee21752d6772eb779a11b8fc4d7cbd0cc5a8888c4206de840464d
MD5 e60d64d321f6413355ff11cb71200243
BLAKE2b-256 239fc1394a4aab88c921384a6635e744f90f9665cb924a8394bdd4770585cbf5

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page