A starter for building a Danbyte plugin. Click “Use this template” (or clone it), rename a few things, and you have a working plugin that adds a model, a REST API, a monitoring check kind, an automation provider, and server-driven UI — with no changes to Danbyte core and no frontend build.
Danbyte plugins are trusted, in-process Python packages (NetBox-style): an operator installs the package, lists it in the
PLUGINSsetting, and restarts. See the full guide: Danbyte docs → Architecture → Plugins.
danbyte_myplugin/
├── apps.py # DanbytePluginConfig — plugin metadata
├── danbyte_plugin.py # THE registration entry point (autodiscovered)
├── models.py # a sample tenant-scoped model (Gadget)
├── serializers.py # DRF serializer (tags + custom fields)
├── viewsets.py # tenant-scoped, RBAC default-closed CRUD
├── api_urls.py # mounted at /api/plugins/<slug>/
├── checks.py # a sample monitoring check kind
└── migrations/
pyproject.toml # packaging (hatchling)
.github/workflows/ # publish to PyPI on release (Trusted Publishing)
Pick a name — e.g. danbyte_acme. Then:
- Rename the
danbyte_myplugin/folder →danbyte_acme/. - In
pyproject.toml:name = "danbyte-acme"andpackages = ["danbyte_acme"]. - In
apps.py:name = "danbyte_acme", and pick aslug(e.g.acme). - Search-and-replace
myplugin→acmeanddanbyte_myplugin→danbyte_acmeacross the package (slugs, URLs, the migration's model,audit_type). - Rename the sample
Gadgetmodel to yours (or delete it and add your own).
Your plugin imports from the host (core, api, auth_api, plugins,
danbyte_checks), so develop it inside a Danbyte environment:
# in your Danbyte checkout, with its virtualenv active
pip install -e /path/to/danbyte-acme # editable install
echo 'PLUGINS=danbyte_acme' >> .env # enable it
python manage.py makemigrations danbyte_acme # generate real migrations
python manage.py migrate
python manage.py runserver # (or restart your services)Open Settings → Deployment → Plugins & services — your plugin appears as
loaded, and its nav item + pages show up (subject to RBAC). Grant yourself the
object-type permission (e.g. gadget) to see and edit rows.
| You want… | Call / mixin |
|---|---|
| A model in RBAC + import/export + eventing | register_object_type("danbyte_acme.Gadget", "Gadgets", "Plugins") |
| Custom fields on it | mix in core.models.CustomFieldsMixin |
| Tags on it | mix in core.models.TaggableMixin |
| It targetable by object-reference custom fields | register_reference_model(ReferenceModel(...)) |
| Change-log / audit | register_audited_model("danbyte_acme.Gadget") |
| A REST API | ship api_urls.py (auto-mounted at /api/plugins/<slug>/) |
| An automation runner | register_automation_provider(kind, runner) |
| An import source / notification channel | register_import_source(...) / register_notification_channel(...) |
| A monitoring check kind | @danbyte_checks.base.register on a Checker |
| Sidebar nav / pages / dashboard panels | register_nav_item / register_page / register_dashboard_panel |
Rules that matter
apps.pyand__init__.pymust be import-safe — no model imports at the top level (Danbyte reads your metadata before the app registry exists).- Every model uses a UUID primary key and a
tenantFK; scope all querysets to the active tenant (theTenantScopedViewSetbase does this). - New endpoints are default-closed — registering the object type is what
makes yours require a
<model>.*grant. Never trust a client-supplied id to belong to the current tenant.
The included workflow publishes on a GitHub Release using Trusted Publishing (OIDC — no token stored):
- On PyPI: create the project (or reserve the name), then Publishing → add a
GitHub publisher: owner
your-org, repodanbyte-acme, workflowpublish.yml, environmentpypi. - In GitHub: create an environment named
pypi. - Cut a GitHub Release (tag e.g.
v0.1.0). The workflow builds and uploads.
Prefer a token? Set a PYPI_API_TOKEN repo secret and pass it to the publish
step (see the comment in .github/workflows/publish.yml). Never commit a
token.
Users then install your plugin with pip install danbyte-acme, add it to
PLUGINS, and apply (migrate + restart).
Apache-2.0, matching Danbyte. Change it to suit your plugin.