What is OpenAdmin?
OpenAdmin is a FastAPI-native library for building admin dashboards. You define pages as plain Python functions decorated with typed helpers — no templates, no separate frontend project, no configuration files to maintain. Every page is a FastAPI router; every widget on that page is just an endpoint.
@page.stat("Total Users")
async def total_users() -> spec.Stat:
return 1_024That function is a normal async def FastAPI handler. It also happens to describe a stat tile that shows up in the admin UI, because OpenAdmin inspects its signature and return type to build a specification the bundled frontend renders.
The core idea
An admin panel is a tree of four kinds of objects:
AdminPanel— the panel itself. It is a small wrapper around aFastAPI()app, meant to be mounted onto your real application withapp.mount("/admin", admin.app).- Sections — top-level groups in the navigation, registered on the panel with
admin.section(...). A section is just a name plus a list of pages. AdminPage— a page inside a section. Internally it holds a FastAPIAPIRouter, so everything you already know about routers, dependencies, and path operations applies.- Components — the widgets on a page: stats, tables, forms, actions, charts, and markdown blocks. Each one is registered with a decorator on an
AdminPage(@page.stat(...),@page.table(...), etc.) and becomes both a real HTTP endpoint and an entry in the page's spec.
AdminPanel
└── section("Library")
└── AdminPage("Books")
├── @page.stat("Total Books")
├── @page.table("All Books")
├── @page.form("Add Book")
└── @page.action("Delete Book")See Components for a full walkthrough of each widget type.
How it fits together
Every decorator does two things at once:
- It registers your function as a real route on the page's router — with FastAPI's usual dependency injection,
Query/Body/Formparameters, pydantic models, and OpenAPI docs. - It records metadata (name, icon, color, the parameters it accepts, and so on) into a
Spec— a plain nestedTypedDictstructure (openadmin.spec.Spec→Section→Page→Component) describing the whole panel.
The panel exposes that structure at GET /api/openadmin.json. The bundled frontend (served from the same panel at /) fetches this spec once to build the navigation and layout, then calls each component's own endpoint — the same one your decorator wrapped — to fetch or refresh its data. Because it's the same endpoint either way, you can curl any widget directly, exercise it from FastAPI's /docs, or write ordinary tests against it.
What's included
- Stats — a single value: a count, a percentage, a boolean.
- Tables — paginated, searchable grids with per-row actions and styled columns (badges, images, links, files).
- Forms — structured forms that submit to your own endpoint, with optional reference fields that look values up from another table.
- Actions — one-off buttons that call an endpoint, either standalone or attached to a table row.
- Charts — bar and pie charts today, with area and line chart types defined in the spec for future support.
- Markdown — static or dynamic rich text blocks for guides, changelogs, or contextual notes.
Because a page is a router and a widget is an endpoint, everything FastAPI already gives you — dependency injection, background tasks, database sessions, response validation, middleware — works unchanged. There is no separate query language or templating layer to learn.
Next steps
- Getting Started — build a minimal panel end to end.
- Components — the full reference for every widget type.
- Authentication — gate the panel behind a login screen.