Skip to main content

Admin interface for Oxyde ORM

Project description

Logo

Oxyde Admin Auto-generated admin panel for Oxyde ORM with zero boilerplate.

PyPI Downloads


Features

  • Automatic CRUD - list, create, edit, delete from your Oxyde models
  • Search & filters - text search across fields, column filters (FK, bool, string)
  • Foreign key handling - select dropdowns with inline create dialog
  • Many-to-many relations - multi-select widget with junction-table sync
  • Enum & array fields - Enum columns rendered as dropdowns, list[T] as array editors
  • Streaming export - CSV / JSON export of large tables in chunks, with row caps
  • Bulk operations - bulk delete and update from the list view
  • Authentication - pluggable sync/async callback, JWT-ready
  • Theming - 3 presets, 17 colors, 8 surface palettes
  • Multi-framework - FastAPI, Litestar, Sanic, Quart and Falcon adapters

oxyde-admin list view

Requirements

  • Python ≥ 3.10
  • oxyde ≥ 0.5.0
  • One of the supported frameworks (fastapi / litestar / sanic / quart / falcon)
  • An ASGI server (e.g. uvicorn, hypercorn)

Installation

pip install oxyde-admin

Quick start

from fastapi import FastAPI
from oxyde import db
from oxyde_admin import FastAPIAdmin

from models import User, Post, Comment

admin = FastAPIAdmin(title="My Admin")
admin.register(User, list_display=["name", "email"], search_fields=["name", "email"])
admin.register(Post, list_display=["title", "is_published"], list_filter=["is_published"])
admin.register(Comment)

app = FastAPI(lifespan=db.lifespan(default="sqlite:///app.db"))
app.mount("/admin", admin.app)

Open http://localhost:8000/admin/ and get a full CRUD interface for your models. The admin ships its own SPA frontend, so no separate frontend build is required — the static assets are served by the same mount.

edit form

Configuration

All adapters accept the same constructor parameters:

Parameter Default Description
title "Oxyde Admin" Title shown in the UI
prefix "/admin" URL prefix (FastAPI / Sanic / Quart / Falcon; on Litestar set the path via mount)
preset Preset.AURA PrimeVue preset
primary_color PrimaryColor.SKY Accent color
surface Surface.SLATE Surface palette
per_page 100 Maximum page size for the list view
export_chunk_size 10_000 Rows per chunk while streaming an export
max_export_rows 100_000 Hard cap on total exported rows
auth_check None Callable (request) -> bool, sync or async
login_url None Where the UI redirects on 401

Frameworks

FastAPI

from oxyde_admin import FastAPIAdmin

admin = FastAPIAdmin(title="My Admin")
# register models...
app.mount("/admin", admin.app)

Litestar

from litestar import Litestar, asgi
from oxyde_admin import LitestarAdmin

admin = LitestarAdmin(title="My Admin")
# register models...

app = Litestar(
    route_handlers=[
        asgi(path="/admin", is_mount=True)(admin.app),
    ],
)

Sanic

from sanic import Sanic
from oxyde_admin import SanicAdmin

admin = SanicAdmin(title="My Admin", prefix="/admin")
# register models...

app = Sanic("MyApp")
admin.register_exception_handlers(app)
app.blueprint(admin.blueprint)

Quart

from quart import Quart
from oxyde_admin import QuartAdmin

admin = QuartAdmin(title="My Admin", prefix="/admin")
# register models...

app = Quart(__name__)
admin.init_app(app)

Falcon

import falcon.asgi
from oxyde_admin import FalconAdmin

admin = FalconAdmin(title="My Admin", prefix="/admin")
# register models...

app = falcon.asgi.App()
admin.init_app(app)

Model registration

admin.register(
    Post,
    list_display=["title", "author_id", "is_published", "views"],
    search_fields=["title", "content"],
    list_filter=["author_id", "is_published"],
    readonly_fields=["views"],
    ordering=["-views"],
    display_field="title",
    column_labels={"author_id": "Author", "is_published": "Published"},
    exportable=True,
    group="Content",
    icon="pi pi-file-edit",
)
Parameter Description
list_display Columns shown in the list view
search_fields Fields included in text search
list_filter Columns available as filters
readonly_fields Fields disabled in the edit form
ordering Default sort order (prefix - for descending)
display_field Field used as label in FK dropdowns
column_labels Custom column headers
exportable Enable CSV/JSON export (default: True)
group Sidebar group name
icon Sidebar icon (PrimeIcons)

You can also auto-register all models at once:

admin.register_all()

# or exclude specific models
admin.register_all(exclude={InternalModel})

Field types

The admin reads field metadata from _db_meta and renders an appropriate widget:

Type Widget
str / int / float Text / number input
bool Toggle
date / datetime Date / datetime picker
UUID Text input
Enum Dropdown with the enum members
list[T] Array editor (chips for primitive item types)
Foreign key Searchable dropdown with inline create dialog
Many-to-many Multi-select; junction rows synced on save

Tip: Foreign-key and M2M target models must also be registered. Use display_field on the target model to control the label shown in dropdowns; otherwise the first string field (or the primary key) is used.

Theming

from oxyde_admin import Preset, PrimaryColor, Surface

admin = FastAPIAdmin(
    title="My Admin",
    preset=Preset.AURA,
    primary_color=PrimaryColor.TEAL,
    surface=Surface.ZINC,
)

themes

Presets: AURA, LARA, NORA

Colors: NOIR EMERALD GREEN LIME ORANGE AMBER YELLOW TEAL CYAN SKY BLUE INDIGO VIOLET PURPLE FUCHSIA PINK ROSE

Surfaces: SLATE GRAY ZINC NEUTRAL STONE SOHO VIVA OCEAN

Authentication

Note: This section describes the current behavior. The authentication flow will be reworked in the future.

Pass an auth_check callback and a login_url:

async def check_admin(request) -> bool:
    token = request.headers.get("Authorization", "").removeprefix("Bearer ")
    return await verify_admin_token(token)

admin = FastAPIAdmin(
    auth_check=check_admin,
    login_url="/auth/login",
)
  • auth_check may be sync or async — the adapter detects this at runtime.
  • GET <prefix>/api/config is intentionally not gated by auth_check so the unauthenticated UI can read login_url and the theme on the login screen.
  • The frontend stores the token in localStorage under the key admin_token and sends it as Authorization: Bearer <token> on every API request. On a 401 it clears the token and redirects to login_url.

Your login_url endpoint must accept POST {"email": "...", "password": "..."} and return {"token": "<...>"} on success, or a non-2xx response with {"detail": "..."} on failure.

API

The admin UI talks to the backend through the following endpoints (relative to the admin prefix):

GET    /api/config
GET    /api/models
GET    /api/models/counts
GET    /api/<model>/schema
GET    /api/<model>?page=&per_page=&ordering=&search=&<filter>=
POST   /api/<model>
GET    /api/<model>/<pk>
PATCH  /api/<model>/<pk>
DELETE /api/<model>/<pk>
GET    /api/<model>/options?search=&limit=&include=
GET    /api/<model>/export?format=csv|json&ids=&ordering=&search=
POST   /api/<model>/bulk-delete   { "ids": [...] }
POST   /api/<model>/bulk-update   { "ids": [...], "data": {...} }

<model> is the table name (e.g. users, not User). Schema responses include x-db-* extensions (primary key, FK target, nullable, default, db type, max length, enum members, array item type, M2M target / through) that you can use to drive a custom UI — see oxyde_admin/schema.py for the full list.

Examples

Working applications with auth, fixtures, FK / M2M relations, and enum / array fields are in examples/ for each supported framework (FastAPI, Litestar, Sanic, Quart, Falcon).

License

This project is licensed under the terms of the MIT license.

Project details


Download files

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

Source Distribution

oxyde_admin-0.4.0.tar.gz (995.7 kB view details)

Uploaded Source

Built Distribution

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

oxyde_admin-0.4.0-py3-none-any.whl (995.6 kB view details)

Uploaded Python 3

File details

Details for the file oxyde_admin-0.4.0.tar.gz.

File metadata

  • Download URL: oxyde_admin-0.4.0.tar.gz
  • Upload date:
  • Size: 995.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for oxyde_admin-0.4.0.tar.gz
Algorithm Hash digest
SHA256 9026d1f12e5a92daafed80a62e127073a17fc2c40c711e5d67913098a09e57f7
MD5 a0869d5b5e8ef95ccf36e29c58089f0e
BLAKE2b-256 475968f79005e23c21acd633761d2d9c0de2bd58db5b14cd3eb16926b4ab8e2f

See more details on using hashes here.

Provenance

The following attestation bundles were made for oxyde_admin-0.4.0.tar.gz:

Publisher: release.yml on mr-fatalyst/oxyde-admin

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file oxyde_admin-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: oxyde_admin-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 995.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for oxyde_admin-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 62a5c0796bd108a279208ae12eaf256bfa50e654bacb1594573ec45e76377c58
MD5 60dcb919660760d6b0fd86e844fd09dc
BLAKE2b-256 f876a9dfd885ae8a20cc0ba79ac96e02f54929e9b39d4fb1576caa881edb5b57

See more details on using hashes here.

Provenance

The following attestation bundles were made for oxyde_admin-0.4.0-py3-none-any.whl:

Publisher: release.yml on mr-fatalyst/oxyde-admin

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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