Skip to content
Packages Examples Agents Blog Get started

Modern Python-first admin framework for Oridecon — HTMX, CRUD, dashboards, and extensions.


Auto-generated admin panel for the Oridecon Framework. Provides CRUD interfaces, bulk actions, role-based access, and audit logging for any domain model — with zero frontend code required.

Built on oridecon-ui for responsive UI components and integrates with oridecon-auth for RBAC permission enforcement. Configure via AdminModule.configure() and pass Resource classes via the resources= argument.

Terminal window
uv add oridecon-admin
# Optional extras
uv add "oridecon-admin[auth,saml,ldap,oauth2,export]"
from oridecon import Application
from oridecon.admin import AdminModule
from oridecon.admin.config import AdminConfig
from oridecon.admin.resources.users import UserResource
from oridecon.sql import DatabaseModule
from oridecon.features import FeatureFlagsModule
async def main() -> None:
async with Application.boot(
modules=[
DatabaseModule.configure(config="sqlite:///admin.db"),
FeatureFlagsModule.configure(),
AdminModule.configure(
config=AdminConfig(title="My App Admin"),
resources=[UserResource],
),
]
) as app:
# ... admin panel served under /admin ...
...
if __name__ == "__main__":
import asyncio
asyncio.run(main())

Resources are Resource subclasses (e.g. UserResource) passed to AdminModule.configure(resources=[...]) — there is no global admin-site registry in oridecon-admin. The admin panel also requires a registered DatabaseProviderProtocol (here via DatabaseModule from oridecon-sql) and FlagManagerProtocol (via FeatureFlagsModule).

Zero-config usage: Call AdminModule.configure() with no arguments to use defaults.

application.yaml
admin:
prefix: /admin
title: "My App Admin"
features:
audit_logging: true
Section titled “Option 2 — Profiles + Environment Variables (recommended)”
Terminal window
export ORI_ADMIN__ENABLED=true
export ORI_ADMIN__TITLE="Production Admin"
from oridecon.admin.config import AdminConfig
config = AdminConfig(
prefix="/admin",
title="My App Admin",
features=AdminFeaturesConfig(audit_logging=True),
)
AdminModule.configure(config)
FieldDefaultEnv varDescription
prefix/adminORI_ADMIN__PREFIXURL prefix for all admin routes
titleOridecon AdminORI_ADMIN__TITLEPanel title shown in browser and header
auth.session_secretchange-me-in-productionORI_ADMIN__AUTH__SESSION_SECRETSecret for signing session cookies (required in production)
auth.session_lifetime86400ORI_ADMIN__AUTH__SESSION_LIFETIMESession validity in seconds (default: 24h)
auth.idle_timeout3600ORI_ADMIN__AUTH__IDLE_TIMEOUTIdle session expiry in seconds
features.audit_loggingtrueORI_ADMIN__FEATURES__AUDIT_LOGGINGLog every write action with user and diff
resource_defaults.per_page20ORI_ADMIN__RESOURCE_DEFAULTS__PER_PAGEDefault rows per page
ui.themesystemORI_ADMIN__UI__THEMEUI colour scheme (light, dark, or system)
MethodDescription
AdminModule.configure(...)Configure with explicit config, auth provider, resources, or controllers
AdminModule.stub()Minimal config for testing
  • Auto CRUD — List, detail, create, edit, delete with zero boilerplate
  • Smart list — Sortable columns, inline filters, pagination, search bar
  • Bulk actions — Multi-select operations with progress and error summaries
  • Row actions — Per-row buttons for custom single-object operations
  • Auth integration — Plugs into oridecon-auth RBAC; per-model permission guards
  • Audit log — Every write action logged with user, timestamp, diff
  • Change history — Per-object change history with diff viewer
  • Password policy — Configurable complexity rules for admin users
  • Custom pagesBaseAdminContributor.get_management_pages() and get_routes() for bespoke views
from oridecon.admin import AdminModule
from oridecon.sql import DatabaseModule
from oridecon.features import FeatureFlagsModule
async with Application.boot(
modules=[
DatabaseModule.configure(config="sqlite:///test.db"),
FeatureFlagsModule.configure(),
AdminModule.stub(),
]
) as app:
# your test code
...

AdminModule.stub() still requires a DatabaseProviderProtocol and a FlagManagerProtocol binding (as in the Quick Start); it simply registers no resources or contributors.

FileWhat it contains
src/oridecon/admin/module.pyAdminModule definition with factory methods
src/oridecon/admin/di/bundle_provider.pyAdminProvider wiring
src/oridecon/admin/config.pyAdminConfig and all config sub-models
src/oridecon/admin/contributors/Contributor registry, resource collection

oridecon-admin features a plugin/contributor system that lets third-party packages extend the admin dashboard without modifying the host application.

Any package can become a contributor by:

  1. Subclassing BaseAdminContributor from oridecon-contracts
  2. Registering it via the oridecon.admin.contributors entry point group
  3. Implementing methods like get_resources(), get_dashboard_widgets(), get_navigation_items(), get_management_pages(), get_settings_panels(), get_routes(), and get_actions()

Contributions are automatically namespaced by the contributor’s package_source to prevent name collisions. Collision behavior is configurable via AdminConfig.contributor_collision_mode ("warn" | "error").

For a complete walkthrough, see the Extension Developer Guide.

[project.entry-points."oridecon.admin.contributors"]
my_plugin = "my_plugin.contributor:MyContributor"

Production deployment guidance, rollback steps, audit-log backup/restore, session revocation, contributor triage, and metrics names live in OPERATOR_RUNBOOK.md.