API reference¶
The public objects, as imported from muffin_admin. The guides explain when to use them;
this is the lookup table.
Imports¶
from muffin_admin import (
AdminHandler,
Plugin,
PWAdminHandler,
PWFilter,
SAAdminHandler,
SAFilter,
)
from muffin_admin.handler import AdminOptions
from muffin_admin.peewee import PWAdminOptions, PWSearchFilter
from muffin_admin.sqlalchemy import SAAdminOptions
from muffin_admin.types import TActionView, TRAConverter, TRAInfo, TRAInputs, TRAProps
Backend imports are optional: PWAdminHandler and SAAdminHandler are exported only when
muffin-peewee-aio or muffin-databases are installed.
Plugin¶
Plugin(app: Application | None = None, **options)
The Muffin plugin, registered as app.plugins["admin"].
| Attribute | Meaning |
|---|---|
name |
"admin"; env prefix and app config prefix |
cfg |
Plugin config; see Configuration |
api |
muffin_rest.API mounted at {prefix}/api without OpenAPI |
auth |
Auth state serialized into ra.json |
handlers |
Registered AdminHandler subclasses, in registration order |
plugin.setup(app, *, name=None, **options) -> bool
plugin.to_ra() -> dict
plugin.route(obj, *paths, **params) -> Callable
setup returns True when the plugin is mounted and False when it is disabled; a disabled
plugin mounts nothing, so every admin route answers 404.
route accepts either a handler class (@admin.route on the class) or a path string
(@admin.route("/user") on the class). With a class it registers the handler and forwards to
api.route; with paths it returns a decorator. Extra params go to muffin_rest.API.route.
Authorization and dashboard callbacks:
plugin.check_auth(fn) -> fn # sets api.authorize and auth["required"]
plugin.get_identity(fn) -> fn # mounts {prefix}/ident, sets auth["identityURL"]
plugin.login(fn) -> fn # mounts {prefix}/login, sets auth["authorizeURL"]
plugin.dashboard(fn) -> fn # adds the "dashboard" key to ra.json
All four return the function unchanged and are used as decorators. See Authentication and Dashboard.
to_ra() serializes the plugin state:
{
"apiUrl": "{prefix}/api",
"auth": {...},
"adminProps": {"title", "disableTelemetry", "mutationMode"},
"appBarLinks": [...],
"version": "...",
"help": None,
"resources": [...],
"locales": {...},
"dashboard": ... | None, # only with a dashboard callback
}
version comes from the installed package metadata (importlib.metadata.version).
AdminHandler¶
class AdminHandler(RESTBase[TVResource, TVCollection]):
meta_class = AdminOptions
meta: AdminOptions
async def __call__(self, request, *, method_name=None, **_) -> Response
async def log(self, request, response, action: str | None) -> None
def get_selected(self, request) -> TVCollection
__call__ runs the Muffin-REST request lifecycle and then log. get_selected returns the
selected objects for bulk actions: the ids query values in the base class, a queryset in the
backends.
@classmethod
def action(*paths, methods=None, hosts=None, icon=None, label=None, view=None,
schema=None, **opts) -> Callable
Behaviour is described in Custom actions. The decorator stores
__route__ = (paths, methods, hosts) and __action__ (the payload sent to react-admin) on the
wrapped method.
Serialization helpers:
@classmethod
def to_ra(cls) -> dict # one resource description
@classmethod
def to_ra_schema(cls, schema_cls, *, resource=True) -> tuple[TRAInputs, TRAInputs]
@classmethod
def to_ra_field(cls, field, source) -> TRAInfo
@classmethod
def to_ra_input(cls, field, source, *, resource=True) -> TRAInfo
@classmethod
def to_ra_filter(cls, flt) -> TRAInfo
to_ra_schema returns (fields, inputs); resource=False is used for action schemas, where
inputs are generated without model lookups.
AdminOptions¶
AdminOptions extends muffin_rest.options.RESTOptions:
limit = 25
limit_max = 100
limit_total = False
icon = ""
label = ""
group = None
id = "id"
create = delete = edit = show = True
actions = ()
columns = ()
help = None
locales = None
ra_order = 0
ra_fields, ra_inputs, ra_filters, ra_refs, ra_links, ra_list_params,
ra_filters_always_on and ra_show_params are class-level overrides. Everything is described
in Resources.
Backend handlers¶
class PWAdminOptions(AdminOptions, PWRESTOptions):
# adds: model, manager, model_pk, delete_recursive
# sets: id = model_pk.name, injects a primary-key filter
class PWAdminHandler(AdminHandler[TVResource, TVCollection],
PWRESTHandler[TVResource, TVCollection]):
meta_class = PWAdminOptions
class SAAdminOptions(AdminOptions, SARESTOptions):
# adds: table, database, table_pk
# sets: id = table_pk.name, injects a primary-key filter
class SAAdminHandler(AdminHandler[TVResource, TVCollection],
SARESTHandler[TVResource, TVCollection]):
meta_class = SAAdminOptions
Both override get_selected, to_ra_field and to_ra_input to map storage types to
react-admin widgets.
PWSearchFilter is a Peewee filter that applies contains() to the column:
from muffin_admin.peewee import PWSearchFilter
Filters¶
PWFilter(name, *, field=None, schema_field=None, operator=None, **meta)
SAFilter(name, *, field=None, schema_field=None, operator=None, **meta)
They are Muffin-REST filters with backend operators; see Querying and Filter reference.
Types¶
From muffin_admin.types:
| Type | Definition |
|---|---|
TActionView |
Literal["show", "edit", "list", "bulk"] |
TRAProps |
dict[str, Any] |
TRAInfo |
tuple[str, TRAProps] — widget name and props |
TRAConverter |
Callable[[Field], TRAInfo] |
TRAInputs |
tuple[tuple[str, TRAInfo], ...] |
TRAReference |
TypedDict(key, source, reference, searchKey), all optional |
TRAActionLink |
TypedDict(label, icon, title, field, filter), all optional |
TRALinks |
tuple[tuple[str, TRAActionLink], ...] |
TRAReference describes an ra_refs entry; TRAActionLink describes an ra_links entry.