Extensible admin interfaces
for FastAPI & Starlette
Instantly generate a comprehensive administrative UI from your SQLAlchemy, SQLModel, Beanie, MongoEngine, or Tortoise ORM models. Built on the modern Tabler UI kit, starlette-admin delivers robust list views, auto-generated forms, data exports, and secure authentication. Configure your entire interface in Python without writing any frontend code.
pip install starlette-admin
Built-in features
Get everything you need right out of the box. Every core feature includes well-documented extension points to support your specific requirements.
Tables
Browse, search, and sort data using pagination, multi-column ordering, and state-preserving URLs. Edit fields inline directly from the list view.
Filters
Build complex nested AND/OR queries directly within the UI. Take advantage of type-aware operators for text, numbers, dates, and booleans.
Forms & uploads
Auto-generate forms that support over 25 field types and complex relational data. Handle file uploads seamlessly to local or S3 storage.
Actions
Create custom bulk and row-level operations using standard Python decorators. Intercept execution using confirmation modals and custom payload forms.
Export & import
Export records instantly to CSV, Excel, JSON, PDF, or any tablib-supported format. Safely import bulk data using a preview-first wizard that enforces strict row-level validation before executing database writes.
Auth & security
Integrate your preferred authentication provider. Deploy with production-ready defaults like CSRF protection and built-in limits for exports and imports.
Inline forms
Manage relational data dynamically. Edit child records directly inside the parent model form without disrupting your workflow.
Dashboards
Design tailored home pages using built-in statistics, charts, and table widgets. You can also integrate a fully custom view.
i18n & timezones
Benefit from out-of-the-box multilingual support and automatic locale-aware formatting with precise timezone handling.
Everything is Python
Build complete administrative interfaces using a pure Python API designed for rapid development, intuitive syntax, and long-term maintainability.
Mount the admin panel
Register a model and mount the admin panel on any FastAPI or Starlette application, then run it using fastapi dev and open /admin.
from fastapi import FastAPI
from sqlalchemy import create_engine
from starlette_admin.contrib.sqla import Admin, ModelView
from models import Base, Post
engine = create_engine("sqlite:///blog.db")
Base.metadata.create_all(engine)
app = FastAPI()
admin = Admin(engine, title="Blog Admin", secret_key="change-me")
admin.add_view(ModelView(Post, icon="fa fa-newspaper"))
admin.mount_to(app)
Views
Tune search, sorting, default ordering, and export formats using plain class attributes. Arrange your create and edit forms using form_layout.
from starlette_admin.contrib.sqla import ModelView
class PostView(ModelView):
fields = ["id", "title", "author", "content", "published", "created_at"]
searchable_fields = ["title", "content"]
fields_default_sort = [("created_at", True)]
exporters = ["csv", "xlsx", "json"]
form_layout = [
("title", "author"),
"content",
("published", "created_at"),
]
admin.add_view(PostView(Post, icon="fa fa-newspaper"))
Fields
Override any auto-detected field to control validation, per-page visibility, and how the system reads and displays values.
from starlette_admin import DateTimeField, RequestAction, StringField, TextAreaField
from starlette_admin.contrib.sqla import ModelView
class PostView(ModelView):
fields = [
"id",
StringField("title", required=True, help_text="Shown on the blog"),
TextAreaField("content", exclude_from_list=True),
StringField(
"author_email",
getter=lambda request, obj: obj.author.email,
formatter={RequestAction.LIST: lambda request, value: value or "unset"},
),
DateTimeField("created_at", read_only=True, exclude_from_create=True),
]
Actions
Attach business operations using a simple decorator. Confirmation modals, custom forms, and flash messages are built directly into the framework.
from starlette.requests import Request
from starlette_admin import ActionSelection, action, flash
from starlette_admin.contrib.sqla import ModelView
class ArticleView(ModelView):
actions = ["publish", "delete"]
@action(
name="publish",
text="Mark as published",
confirmation="Publish the selected articles?",
submit_btn_text="Yes, publish",
)
async def publish(self, request: Request, selection: ActionSelection) -> None:
articles = await selection.rows()
for article in articles:
article.published = True
flash(request, f"{len(articles)} articles published.", "success")
Authentication
Implement three standard methods around your own credential check. The system handles the login page, sessions, and redirects for you.
from starlette.requests import Request
from starlette_admin.auth import AdminUser, AuthProvider, LoginFailed
class MyAuthProvider(AuthProvider):
async def login(self, username, password, remember_me, request: Request) -> None:
if not await check_credentials(username, password):
raise LoginFailed("Invalid username or password")
request.session["username"] = username
async def authenticate(self, request: Request) -> AdminUser | None:
if username := request.session.get("username"):
return AdminUser(username=username)
return None
async def logout(self, request: Request) -> None:
request.session.clear()
admin = Admin(engine, auth_provider=MyAuthProvider(), secret_key=SECRET)
Dashboard
Compose the admin home page using statistic, chart, and table widgets that query live data on every request.
from starlette_admin import CardRowWidget, ChartWidget, CustomView, StatWidget
dashboard = CardRowWidget(
children=[
StatWidget(title="Orders", value_callback=count_orders, countup=True),
StatWidget(title="Revenue", value_callback=sum_revenue, color="success"),
ChartWidget(title="Sales", chart_type="area", series_callback=sales_series),
]
)
admin = Admin(
engine,
title="Shop Admin",
secret_key="change-me",
index_view=CustomView(menu_label="Dashboard", icon="fa fa-home", widget=dashboard),
)
Plugins & extensions
Every layer is replaceable. Ship features as self-contained plugins or hook into any of the dedicated extension points to tailor the framework to your domain.
Zero-boilerplate plugins
Install a plugin package and pass it directly to your Admin instance. Fields, converters, templates, and assets wire themselves together automatically, delivering complex features instantly.
Hook into any component
Predefined interfaces allow you to swap or augment each concern independently. Subclass the base you need and register it. You can customize everything from the authentication flow to the export formats.
- Custom fields
BaseField - Custom filters
BaseFilter - Exporters
BaseExporter - Importers
BaseImporter - Themes
BaseTheme - Auth providers
BaseAuthProvider - Storage backends
BaseStorage - Dashboard widgets
BaseWidget - Templates
templates_dir