Skip to main content

FastAPI + HTMX + Jinja2 admin interface framework — a modern replacement for Flask-Admin

Project description

fasthx-admin

FastAPI + HTMX + Jinja2 admin interface framework — a modern replacement for Flask-Admin.

Features

  • Auto-generated CRUD routes from SQLAlchemy models
  • Dark/light theme with Bootstrap 5.3
  • HTMX-powered interactions (search, sorting, polling, dependent dropdowns)
  • Accordion-grouped form sections
  • Custom column formatters and row actions
  • OIDC/Keycloak authentication (with AUTH_DISABLED dev mode)
  • Deploy wizard with real-time progress tracking
  • Responsive sidebar navigation

Installation

pip install fasthx-admin

For development (includes uvicorn):

pip install fasthx-admin[dev]

Quick Start

from contextlib import asynccontextmanager

from fastapi import FastAPI
from starlette.middleware.sessions import SessionMiddleware

from fasthx_admin import Admin, CRUDView, Base, init_db

# 1. Define your models
from sqlalchemy import Column, Integer, String

class Customer(Base):
    __tablename__ = "customers"
    id = Column(Integer, primary_key=True)
    name = Column(String(100), nullable=False)
    sid = Column(String(50), nullable=False)

    __admin_category__ = "CRM"
    __admin_icon__ = "building"
    __admin_name__ = "Customers"

# 2. Initialise the database
engine = init_db("sqlite:///./app.db", connect_args={"check_same_thread": False})

# 3. Create the app
@asynccontextmanager
async def lifespan(app):
    Base.metadata.create_all(bind=engine)
    yield

app = FastAPI(lifespan=lifespan)
app.add_middleware(SessionMiddleware, secret_key="change-me")

# 4. Create the admin and register views
admin = Admin(app, title="My Admin")

class CustomerView(CRUDView):
    model = Customer
    column_list = ["id", "name", "sid"]

admin.add_view(CustomerView)

Run with auth disabled for development:

AUTH_DISABLED=1 uvicorn app:app --reload

CRUDView Configuration

Subclass CRUDView and set class-level attributes:

Attribute Description
model SQLAlchemy model class (required)
name URL prefix (defaults to __tablename__)
display_name Sidebar label (defaults to model's __admin_name__)
category Sidebar group (defaults to model's __admin_category__)
icon Bootstrap Icons name (defaults to model's __admin_icon__)
column_list Columns to show in the list view
column_exclude Columns to exclude (alternative to column_list)
column_labels Display name overrides, e.g. {"customer_id": "Customer"}
column_formatters {col: fn(value, obj) -> html_string}
column_searchable Columns to search (defaults to all String columns)
column_sortable Columns that can be sorted
form_columns Editable fields (defaults to all except id)
form_sections Accordion groups: {"Section": ["field1", "field2"]}
form_widget_overrides Per-field HTMX attrs or select choices
row_actions Custom action buttons per row
htmx_columns Auto-polling cells: {"field": {"url": "...", "trigger": "every 3s"}}
page_size Records per page (default 20)
can_create / can_edit / can_delete Permission flags

Custom Endpoints

Override setup_endpoints() on your CRUDView subclass to add custom routes:

class OrchestratorView(CRUDView):
    model = Orchestrator

    def setup_endpoints(self):
        @self.router.post(f"/{self.name}/{{item_id}}/build")
        async def build(request: Request, item_id: int, db=Depends(get_db)):
            # custom logic
            return HTMLResponse("", headers={"HX-Redirect": f"/{self.name}"})

Admin Class

admin = Admin(
    app,
    title="My Admin",           # Sidebar brand + page titles
    static_url="/static/fasthx-admin",  # Where package statics are mounted
    public_pages={"login.html"},        # Pages that skip auth check
)

The Admin instance:

  • Mounts built-in static files (CSS, JS)
  • Sets up Jinja2 templates from the package
  • Wraps template responses with nav context + auth check
  • Provides admin.templates for rendering custom pages

Model Metadata

Set these on your SQLAlchemy model classes for automatic sidebar grouping:

class MyModel(Base):
    __tablename__ = "my_models"
    __admin_category__ = "Section Name"  # Sidebar group
    __admin_icon__ = "table"             # Bootstrap Icons name
    __admin_name__ = "My Models"         # Display label

Environment Variables

Variable Purpose Default
AUTH_DISABLED Bypass authentication (1/true/yes) disabled
SESSION_SECRET Session signing key (set in your app)
OIDC_SECRETS Path to client_secrets.json ./client_secrets.json

Running the Demo

cd examples/demo
pip install -e ../..
pip install uvicorn[standard]
AUTH_DISABLED=1 uvicorn app:app --reload

Open http://127.0.0.1:8000

Project details


Release history Release notifications | RSS feed

This version

0.1.1

Download files

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

Source Distribution

fasthx_admin-0.1.1.tar.gz (27.0 kB view details)

Uploaded Source

Built Distribution

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

fasthx_admin-0.1.1-py3-none-any.whl (30.1 kB view details)

Uploaded Python 3

File details

Details for the file fasthx_admin-0.1.1.tar.gz.

File metadata

  • Download URL: fasthx_admin-0.1.1.tar.gz
  • Upload date:
  • Size: 27.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.14

File hashes

Hashes for fasthx_admin-0.1.1.tar.gz
Algorithm Hash digest
SHA256 5b8dff69a7990b93d1eb2095ad45be9561f0a4f2094ed7903226a44a561c4531
MD5 52e92703da9daa90df4846cc3f7b1974
BLAKE2b-256 74c38b3881d7043792647518cb2f6c4d7661da2db8bc9a90b8cecc751d6f7fc8

See more details on using hashes here.

File details

Details for the file fasthx_admin-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: fasthx_admin-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 30.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.14

File hashes

Hashes for fasthx_admin-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 ea41c51cfa58a3be8524ced648b27a0cc7ffb91aacf866a46198822146e89f80
MD5 f56354db022d9eb00dd631bb2b793056
BLAKE2b-256 3935ea92f3638cb60ffafec2a722a436572729f90b0634fe2a6a9229b229a7c8

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