Skip to content

Plugin Structure

A MedUX plugin is a standard Python package that follows GDAPS conventions. This page documents the expected layout and the purpose of each file.

Directory Layout

medux-myplugin/
├── src/
│   └── medux/
│       └── plugins/
│           └── myplugin/
│               ├── __init__.py
│               ├── apps.py              # PluginConfig with PluginMeta
│               ├── models.py            # Django models
│               ├── views.py             # Views
│               ├── urls.py              # URL patterns
│               ├── admin.py             # Django admin registration
│               ├── conf.py              # Plugin-specific settings
│               ├── menus.py             # IMenuItem definitions
│               ├── scoped_settings.py   # Scoped settings registration
│               ├── gdaps_hooks.py       # Hook implementations
│               ├── api/
│               │   └── interfaces.py    # Plugin-provided interfaces
│               ├── migrations/
│               ├── static/
│               │   └── myplugin/
│               └── templates/
│                   └── myplugin/
├── tests/
│   ├── __init__.py
│   ├── settings.py          # Test settings (imports from medux.tests.settings)
│   └── test_*.py
├── pyproject.toml
└── README.md

Key Files

apps.py

The plugin's AppConfig. Must inherit from MeduxPluginAppConfig and define a PluginMeta inner class for GDAPS metadata.

from medux.common.api import MeduxPluginAppConfig

class MyPluginConfig(MeduxPluginAppConfig):
    name = "medux.plugins.myplugin"
    verbose_name = "My Plugin"

    class PluginMeta:
        pass

urls.py

Standard Django URL patterns. These are collected automatically by GDAPS's PluginManager.urlpatterns().

Menu item definitions using IMenuItem. Imported at startup for GDAPS to discover.

scoped_settings.py

Scoped settings registration. Auto-discovered by Conjunto at startup.

api/interfaces.py

Interfaces that this plugin provides for other plugins to implement. Follow the GDAPS interface pattern.

gdaps_hooks.py

Implementations of interfaces defined by MedUX core or other plugins.

Entry Point

The plugin must register itself via a Python entry point in pyproject.toml:

[project.entry-points."medux.plugins"]
myplugin = "medux.plugins.myplugin:apps.MyPluginConfig"

This is how GDAPS discovers the plugin at startup.

Local development layout

During the MedUX Alpha phase, a plugin is developed alongside editable sibling checkouts of medux and conjunto:

~/Projekte/
├── medux/                # git checkout, overlaid as editable
├── conjunto/             # git checkout, overlaid as editable
├── gdaps/                # optional, only for GDAPS itself
└── medux-myplugin/       # this plugin
    └── pyproject.toml    # deps resolve from Git main via [tool.uv.sources]

The plugin's pyproject.toml lists medux in [project.dependencies] and pins its source in [tool.uv.sources] to the Git main branch (medux = { git = "https://gitlab.com/nerdocs/medux/medux.git", rev = "main" }) because MedUX has no PyPI release during alpha. make dev-local runs uv sync (which resolves against that Git URL) and then overlays the sibling checkouts as editable installs via uv pip install --python .venv/bin/python --no-deps -e ../<pkg> — tracked files are never mutated. See Plugin Development for the full workflow.

Namespace

All MedUX plugins live under the medux.plugins namespace package. This means:

  • The package path is src/medux/plugins/myplugin/
  • __init__.py files in medux/ and medux/plugins/ should be empty or use implicit namespace packages
  • The name in AppConfig is "medux.plugins.myplugin"