Skip to content

Admin Dashboard

kokage-ui can auto-generate a Django-like admin panel from your Pydantic models. Register models with AdminSite and get a full management interface with sidebar navigation, DataGrid list views, create/edit forms, detail views, bulk actions, and CSV export.

Quick Start

from fastapi import FastAPI
from kokage_ui import KokageUI, AdminSite, InMemoryStorage
from pydantic import BaseModel, Field

app = FastAPI()
ui = KokageUI(app)

class User(BaseModel):
    id: str = ""
    name: str = Field(min_length=1)
    email: str = ""
    is_active: bool = True

class Product(BaseModel):
    id: str = ""
    name: str = Field(min_length=1)
    price: float = Field(ge=0)

admin = AdminSite(app, prefix="/admin", title="My Admin")
admin.register(User, storage=InMemoryStorage(User))
admin.register(Product, storage=InMemoryStorage(Product))

This generates:

  • Dashboard at /admin/ — overview with model cards and item counts
  • List pages at /admin/user/, /admin/product/ — DataGrid with sort, filter, pagination
  • Create/Edit/Detail/Delete pages for each model
  • Bulk delete and CSV export endpoints
  • Sidebar navigation with all registered models

AdminSite Parameters

Parameter Type Description
app FastAPI FastAPI application instance
prefix str URL prefix (default: "/admin")
title str Site title in navbar (default: "Admin")
auth_check Callable | None (Request) -> user \| None for authentication
theme str DaisyUI theme (default: "corporate")
logout_url str Logout URL for UserMenu (default: "/logout")

register() Parameters

Parameter Type Description
model type[BaseModel] Pydantic model class
storage Storage Storage backend
name str URL slug (default: auto from model name)
title str Display name (default: ModelName + "s")
icon str Sidebar icon (default: first letter)
list_fields list[str] | None Fields to show in list view
search_fields list[str] | None Searchable fields
form_exclude list[str] | None Fields to exclude from forms
list_exclude list[str] | None Fields to exclude from list
per_page int Items per page (default: 20)
id_field str Primary key field (default: "id")

Authentication

Protect the admin panel by providing an auth_check function:

async def get_user(request: Request):
    token = request.cookies.get("auth_token")
    if not token:
        return None
    return {"username": "admin", "role": "admin"}

admin = AdminSite(app, auth_check=get_user)

When auth_check returns None, all admin routes redirect to /login.

With SQLModel Storage

from sqlalchemy.ext.asyncio import create_async_engine
from kokage_ui import SQLModelStorage, create_tables

engine = create_async_engine("sqlite+aiosqlite:///admin.db")

@app.on_event("startup")
async def startup():
    await create_tables(engine)

admin = AdminSite(app)
admin.register(User, storage=SQLModelStorage(User, engine))

Generated Routes

For each registered model (e.g., User with prefix /admin):

Method Path Description
GET /admin/ Dashboard with model cards
GET /admin/user/ List page (DataGrid)
GET /admin/user/_list List fragment (htmx)
POST /admin/user/_bulk_delete Bulk delete
GET /admin/user/_csv CSV export
GET /admin/user/new Create form
POST /admin/user/new Create handler
GET /admin/user/{id} Detail page
GET /admin/user/{id}/edit Edit form
POST /admin/user/{id}/edit Edit handler
DELETE /admin/user/{id} Delete handler