Skip to content

Backend Plugin API

A backend plugin is a reusable Django app.

Also see the Django docs on Advanced tutorial: How to write reusable apps.

🎁 No python packaging here

We don't use any python packaging techniques, opting to simply zip up a directory of files. You can ignore the part of the Django tutorial that goes into that part.

You don't need a pyproject.toml, setup.cfg, or setup.py.

The rationale behind this is so the packaging mechanism is the same whether it's a frontend or backend plugin.

Directory structure

A backend-only plugin can have everything in the main plugin directory:

example-plugin/
├── apps.py
├── __init__.py
├── urls.py
└── views.py

apps.py

This is essential and what we use to find out the root of the plugin directory. It doesn't have to have any content, but you must include it.

You can use it to include an AppConfig for your plugin.

__init__.py

This is how python knows a directory is a python module. It might not actually be needed here, I should check!

urls.py

An optional file for you to register any URL patterns.

Here is a simple example:

python
from django.urls import path

from .views import simple_view

urlpatterns = [path("example-endpoint/", simple_view, name="example-route")]

See https://docs.djangoproject.com/en/5.0/topics/http/urls/ for more info on what to put in there, with lots of examples.

views.py

This is not anything specific to Karrot plugins, but just conventionally used to hold views.

For the above example, it could contain:

python
from rest_framework.decorators import api_view
from rest_framework.response import Response


@api_view(["GET"])
def simple_view(request):
    return Response({"yay": "it worked"})

All the other Django goodies...

As it's just a standard Django app, you can include models, migrations, signals, etc.

Background and periodic tasks

We have a huey task queue, so if you want to run background, or periodic tasks, use that! (By convention in a file named tasks.py).

In combination with a frontend plugin

If you also have frontend parts to your plugin, you can put the backend in a subfolder. It uses the location of apps.py to find the backend plugin directory.

For example:

example-plugin/
├── backend
│   ├── apps.py
│   ├── __init__.py
│   ├── urls.py
│   └── views.py
└── frontend
    ├── main.js
    └── manifest.json