Extensions add UI, menus, and workspace tools. They are discovered from pip packages.
pip install medics-ext-example
medics
Loaded extensions appear under the Extensions menu and, if they provide a UI, can open a tab or window. Enable, disable, and inspect them from the extension manager dialog.
medics --create-ext
# or with a name:
medics --create-ext medics-ext-my-tool
A typical layout of an extension:
medics-ext-my-tool/
├── medics_ext_my_tool/
│ ├── __init__.py # ExtensionInterface implementation
│ ├── extension.json # Display metadata
│ └── ui/
│ └── main_widget.py # Optional PySide6 widget
├── tests/
├── pyproject.toml
└── README.md
Every extension implements:
def get_name(self) -> str: ...
def get_version(self) -> str: ...
def get_description(self) -> str: ...
def get_author(self) -> str: ...
def get_category(self) -> str: ...
def initialize(self, app_context) -> bool: ...
def cleanup(self) -> None: ...
def show_extension(self) -> None: ...
initialize(app_context) receives the running MedICSMain instance, so the extension
can use the workspace, config, event bus, menus, and docks.
extension.json{
"name": "My Tool",
"version": "1.0.0",
"description": "Does XYZ",
"author": "Your Name",
"category": "Image Analysis",
"enabled": true,
"windowed": true,
"icon": null
}
pyproject.toml)[project.entry-points."medics.extensions"]
my_tool = "medics_ext_my_tool:MyToolExtension"
Lifecycle in short: discover → initialize(app_context) → menu/toolbar action → show_extension() → cleanup() on unload.
Run from the extension project directory:
medics --build-ext # plain Python wheel (default)
medics --build-ext --protect # Cython-compiled, source-stripped
medics --build-ext -p # same as --protect
medics --build-ext --upload # build, then upload to PyPI (you must have an PyPI account)
medics --build-ext --upload --test-pypi