Reference ImSwitch v2 plugin. A contact-angle goniometer that demonstrates the full plugin contract: backend controller, React widget, manifest, Module Federation bundle, Docker build, and SDK-only dependencies.
If you want to write your own plugin, start here. Copy this directory,
rename goniometer → yourapp, and edit controller.py and
ui/src/GoniometerWidget.jsx.
imswitch-plugin-goniometer/
├── pyproject.toml # entry-point registration
├── Dockerfile # builds a wheel artifact
├── src/imswitch_plugin_goniometer/
│ ├── __init__.py # register() entry point
│ ├── plugin.toml # declarative manifest
│ ├── controller.py # SDK-based controller
│ ├── algorithm.py # framework-free image processing
│ └── ui/dist/ # populated by `npm run build`
└── ui/
├── package.json
├── webpack.config.js # ModuleFederationPlugin config
├── public/index.html # dev shell only
└── src/
├── index.js # bootstrap
└── GoniometerWidget.jsx # the React component
- ImSwitch ≥ 2.1 (ships the
imswitch.plugin_sdkandimswitch.plugin_managermodules). - Python ≥ 3.10.
- Node.js ≥ 18 (only for building the React bundle).
# 1. Build the React bundle (produces ui/dist/remoteEntry.js)
cd ui && npm install && npm run build && cd ..
# 2. Copy it into the package
cp -r ui/dist src/imswitch_plugin_goniometer/ui/
# 3. Build the Python wheel
python -m build --wheelOr do all three in one shot via Docker:
docker build --target=artifact --output=./wheels .Into a running ImSwitch (host or container):
pip install ./wheels/imswitch_plugin_goniometer-0.2.0-py3-none-any.whlThe PluginManager discovers it on the next ImSwitch start via the
imswitch.plugins entry-point. The widget appears in the side menu under
Measurement → Goniometer.
# host side
mkdir -p ~/imswitch-plugins
git clone https://github.com/openUC2/imswitch-plugin-goniometer \
~/imswitch-plugins/goniometer
cd ~/imswitch-plugins/goniometer/ui
npm install && npm run build
cp -r dist ../src/imswitch_plugin_goniometer/ui/
# run ImSwitch with the directory bind-mounted
docker run --rm \
-p 8001:8001 \
-v ~/imswitch-plugins:/opt/imswitch/plugins \
-e IMSWITCH_PLUGIN_DIR=/opt/imswitch/plugins \
openuc2/imswitch:latest# terminal 1: backend
imswitch # http://localhost:8001/plugin/goniometer/api/...
# terminal 2: frontend with hot reload
cd ui && npm run dev # http://localhost:3101 — standalone dev shellFor end-to-end hot-reload inside the actual ImSwitch shell, configure your
dev ImSwitch to proxy /plugin/goniometer/ui/* to localhost:3101.
All endpoints live under /plugin/goniometer/api.
| Method | Path | Purpose |
|---|---|---|
| GET | /get_config |
Current algorithm parameters |
| POST | /set_config |
Patch parameters |
| POST | /reset_config |
Restore defaults |
| GET | /snap |
Grab + crop + return base64 JPEG |
| POST | /set_crop |
Set crop ROI (x1,y1,x2,y2) |
| POST | /reset_crop |
Clear crop |
| GET | /get_crop |
Current ROI |
| GET | /measure_auto |
Automatic contact-angle measurement |
| POST | /measure_manual |
3-point manual measurement |
| GET | /get_focus_metric |
Laplacian-variance focus score |
| GET | /get_measurements |
History |
| POST | /add_measurement |
Append to history |
| POST | /clear_measurements |
Clear history |
| GET | /get_camera_settings |
Exposure / gain |
| POST | /set_camera_settings |
Update exposure / gain |
Events are emitted over the per-plugin Socket.IO namespace
/plugin/goniometer:
measurement→{left_angle, right_angle, timestamp}after every auto run.
MIT — see LICENSE.