Admin interface for Oxyde ORM
Project description
Oxyde Admin Auto-generated admin panel for Oxyde ORM with zero boilerplate.
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 -
Enumcolumns 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
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.
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_fieldon 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,
)
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_checkmay be sync or async — the adapter detects this at runtime.GET <prefix>/api/configis intentionally not gated byauth_checkso the unauthenticated UI can readlogin_urland the theme on the login screen.- The frontend stores the token in
localStorageunder the keyadmin_tokenand sends it asAuthorization: Bearer <token>on every API request. On a401it clears the token and redirects tologin_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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9026d1f12e5a92daafed80a62e127073a17fc2c40c711e5d67913098a09e57f7
|
|
| MD5 |
a0869d5b5e8ef95ccf36e29c58089f0e
|
|
| BLAKE2b-256 |
475968f79005e23c21acd633761d2d9c0de2bd58db5b14cd3eb16926b4ab8e2f
|
Provenance
The following attestation bundles were made for oxyde_admin-0.4.0.tar.gz:
Publisher:
release.yml on mr-fatalyst/oxyde-admin
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
oxyde_admin-0.4.0.tar.gz -
Subject digest:
9026d1f12e5a92daafed80a62e127073a17fc2c40c711e5d67913098a09e57f7 - Sigstore transparency entry: 1417699181
- Sigstore integration time:
-
Permalink:
mr-fatalyst/oxyde-admin@0dd991f0bc4881c34354b3ce35e29bb381348bbe -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/mr-fatalyst
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@0dd991f0bc4881c34354b3ce35e29bb381348bbe -
Trigger Event:
push
-
Statement type:
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
62a5c0796bd108a279208ae12eaf256bfa50e654bacb1594573ec45e76377c58
|
|
| MD5 |
60dcb919660760d6b0fd86e844fd09dc
|
|
| BLAKE2b-256 |
f876a9dfd885ae8a20cc0ba79ac96e02f54929e9b39d4fb1576caa881edb5b57
|
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
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
oxyde_admin-0.4.0-py3-none-any.whl -
Subject digest:
62a5c0796bd108a279208ae12eaf256bfa50e654bacb1594573ec45e76377c58 - Sigstore transparency entry: 1417699187
- Sigstore integration time:
-
Permalink:
mr-fatalyst/oxyde-admin@0dd991f0bc4881c34354b3ce35e29bb381348bbe -
Branch / Tag:
refs/tags/v0.4.0 - Owner: https://github.com/mr-fatalyst
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@0dd991f0bc4881c34354b3ce35e29bb381348bbe -
Trigger Event:
push
-
Statement type: