G
YouTube TikTok Games
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ If applicable, add screenshots to help explain your problem.
**Installation information**

- DataLab installation type ["Python package" or "stand-alone Windows version"]
- Copy/paste here the contents of "About DataLab installation..." window (Menu "?")
- Copy/paste here the contents of "Installation and configuration..." window (Menu "?")

**Additional context**
Add any other context about the problem here.
41 changes: 22 additions & 19 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ DataLab/
│ │ └── builtin/ # Built-in plugins (data folder, not a package)
│ ├── tests/ # pytest test suite
│ ├── locale/ # Translations (.po files)
│ ├── config.py # Configuration management
│ ├── config/ # Configuration management (package)
│ └── objectmodel.py # Object data model for GUI
├── doc/ # Sphinx documentation
│ ├── locale/fr/ # French documentation translations
Expand Down Expand Up @@ -271,7 +271,7 @@ self.register_2_to_1(
)
```

**Code Location**: `datalab/gui/processor/base.py` (lines ~1764, 1886)
**Code Location**: `datalab/gui/processor/base.py` (`_check_signal_xarray_compatibility()`, called by `prepare_2_to_1_pairs()`, `compute_2_to_1()` and `compute_n_to_1()`)

### 3. Action Handler Pattern (Menu Management)

Expand All @@ -288,16 +288,19 @@ self.register_2_to_1(

```python
# In SignalActionHandler or ImageActionHandler
def setup_processing_actions(self) -> None:
"""Setup processing menu actions."""

# Reference registered processor operation
act = self.action_for("my_processing_func")

# Add to menu
self.processing_menu.addAction(act)
def create_first_actions(self):
"""Create actions that are added to the menus in the first place"""
super().create_first_actions()

# Actions created in a category are added to the corresponding menu
with self.new_category(ActionCategory.PROCESSING):
with self.new_menu(_("My submenu")): # Submenu
# Reference registered processor operation
self.action_for("my_processing_func")
```

Actions added at the end of the menus are created in `create_last_actions()`. Reopening an existing built-in submenu (same title in the same category, e.g. "Axis transformation" created by `BaseActionHandler`) replaces its contents: list all the actions of that submenu, as `SignalActionHandler` and `ImageActionHandler` do.

**Menu Organization**:

Menus are organized by function:
Expand All @@ -324,7 +327,7 @@ generated with `scripts/print_datalab_menus.py`).

**Key Classes**:
- `PluginBase`: Abstract base class for all plugins (uses metaclass `PluginBaseMeta`)
- `PluginInfo`: Plugin metadata dataclass (name, version, description, icon)
- `PluginInfo`: Plugin metadata dataclass (name, version, description, icon, id, capabilities, documentation_url)
- `PluginRegistry`: Metaclass that auto-registers plugin subclasses

**Example: Creating a Plugin**
Expand Down Expand Up @@ -366,7 +369,7 @@ class MyPlugin(PluginBase):

**Plugin Discovery**: Plugins are loaded from:
1. `datalab/plugins/builtin/` (built-in)
2. User plugin directory (`~/.DataLab/plugins`)
2. User plugin directory (`~/.DataLab_v1/plugins`, the suffix being the major version of DataLab)
3. Custom plugin directory (configurable in preferences)
4. For frozen apps, from `plugins/` directory next to executable

Expand Down Expand Up @@ -596,8 +599,7 @@ menu_title = "Processing" # Not translatable!
refused), increase its `contract_version` (and its qualification) in Sigima in the same change,
**whatever the releases of DataLab**: Sigima is a reference of its own. Only previously refused
inputs now accepted, changes without effect on the result, or changes covered by a versioned
rule of the execution context (image ROI convention, X alignment) do not require it. The 1.4
exception (contracts kept at version 1) was one-off and does not apply anymore. Then update the
rule of the execution context (image ROI convention, X alignment) do not require it. In Sigima 1.4.0, 16 contracts are at version 2 (image profiles, `product`, `extract_roi`, `extract_rois` and the image analyses giving geometric results, listed in the Sigima 1.4 release notes), while the others kept version 1, even when their result had changed since 1.3.0 (e.g. `resampling`): this one-off exception does not apply anymore. Then update the
DataLab provenance tests that check a contract version
(`datalab/tests/features/common/provenance_*_test.py`). Full rules: Sigima
`doc/contributing/guidelines.rst` and `doc/user_guide/contracts.rst`.
Expand All @@ -622,9 +624,10 @@ menu_title = "Processing" # Not translatable!

4. **Add menu action** (`datalab/gui/actionhandler.py`):
```python
def setup_processing_actions(self) -> None:
act = self.action_for("my_feature")
self.processing_menu.addAction(act)
def create_first_actions(self):
super().create_first_actions()
with self.new_category(ActionCategory.PROCESSING):
self.action_for("my_feature")
```

5. **Add tests** (`datalab/tests/features/signal/`):
Expand Down Expand Up @@ -674,7 +677,7 @@ menu_title = "Processing" # Not translatable!

1. **Check processor registration**: Look in `register_operations()` methods
2. **Verify action handler**: Search `actionhandler.py` for `action_for("function_name")`
3. **Test in isolation**: Use pytest with `--ff` flag (fail-fast)
3. **Test in isolation**: Use pytest with `--ff` flag (failed tests first), or `-x` to stop at the first failure
4. **Check translations**: Missing `_()` wrapper causes English-only UI
5. **Verify imports**: Ensure function is in `__all__` export list

Expand Down Expand Up @@ -797,7 +800,7 @@ Follow [RELEASING.md](../RELEASING.md). **Never create a GitHub release by hand*
| `datalab/gui/processor/image.py` | Image processor registration |
| `datalab/gui/processor/base.py` | Base processor class (generic methods) |
| `datalab/gui/actionhandler.py` | Menu and action management |
| `datalab/config.py` | Configuration, `_()` translation function |
| `datalab/config/` | Configuration package, `_()` translation function |
| `datalab/plugins/base.py` | Plugin system implementation (public names re-exported by `datalab.plugins`) |
| `datalab/gui/plugins/config.py` | Plugin configuration dialog |
| `datalab/control/baseproxy.py` | Abstract base proxy (API definition) |
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,16 +63,16 @@ feature (this requires to install DataLab as a Python package)

DataLab requires **Python 3.10+**.

From [PyPI](https://pypi.org/project/datalab-platform/):
From [PyPI](https://pypi.org/project/datalab-platform/), with the Qt bindings (`qt` extra):

```bash
pip install datalab-platform
pip install "datalab-platform[qt]"
```

From [conda-forge](https://anaconda.org/conda-forge/datalab-platform):
From [conda-forge](https://anaconda.org/conda-forge/datalab):

```bash
conda install -c conda-forge datalab-platform
conda install conda-forge::datalab
```

On [NixOS](https://nixos.org/), DataLab is available from the [NGI Forge](https://ngi.nixos.org/app/datalab), packaged by the [Nix@NGI team](https://nixos.org/community/teams/ngi/) (an NLnet partner) as part of DataLab's NGI0 Commons Fund grant.
Expand Down
2 changes: 1 addition & 1 deletion RELEASING.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

A release takes two steps, both run by [`.github/workflows/release.yml`](.github/workflows/release.yml), which relies on the [release actions](https://github.com/DataLab-Platform/release-actions) shared by the DataLab Platform projects:

1. **Prepare**: pushing a release tag checks the tag, runs the tests, builds the release files (wheel, sdist, French and English PDF documentation, smoke-tested MSI installer), attests their build provenance and creates a **draft** GitHub release with these files and their `SHA256SUMS`. Nothing is published at this stage.
1. **Prepare**: pushing a release tag checks the tag, runs the tests, builds the release files (wheel, sdist, French and English PDF documentation, smoke-tested MSI installer), attests the build provenance of the wheel, the sdist and the MSI installer, and creates a **draft** GitHub release with these files and their `SHA256SUMS`. Nothing is published at this stage.
2. **Publish**: when a maintainer publishes the draft release, its wheel and sdist are checked (checksums and attestations) and uploaded to PyPI, then the documentation is deployed to [datalab-platform.com](https://datalab-platform.com/). A release created by hand has none of these files, so nothing is published.

## One-time prerequisites
Expand Down
4 changes: 2 additions & 2 deletions datalab/control/proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -421,8 +421,8 @@ def add_annotations_from_items(
"""Add object annotations (annotation plot items).

Args:
itemsTrue: annotation plot items
refresh_plotTrue: refresh plot. Defaults to True
items: annotation plot items
refresh_plot: refresh plot. Defaults to True
panel: panel name (valid values: "signal", "image").
If None, current panel is used
"""
Expand Down
2 changes: 1 addition & 1 deletion datalab/control/remote.py
Original file line number Diff line number Diff line change
Expand Up @@ -943,7 +943,7 @@ class RemoteClient(BaseProxy):
Here is a simple example of how to use RemoteClient in a Python script
or in a Jupyter notebook:

>>> from datalab.remote import RemoteClient
>>> from datalab.control.remote import RemoteClient
>>> proxy = RemoteClient()
>>> proxy.connect()
Connecting to DataLab XML-RPC server...OK (port: 28867)
Expand Down
5 changes: 2 additions & 3 deletions datalab/gui/macros_templates/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,8 @@

Additional templates can be dropped into the user templates directory
(by default ``<USER_CONFIG_DIR>/macro_templates`` — typically
``~/.DataLab/macro_templates`` on Linux/macOS and
``%APPDATA%\\.DataLab\\macro_templates`` on Windows). The location can be
overridden through ``Conf.macro_templates_path``.
``~/.DataLab_v1/macro_templates``, i.e. ``%USERPROFILE%\\.DataLab_v1\\macro_templates``
on Windows). The location can be overridden through ``Conf.macro_templates_path``.

Any ``*.py`` file placed in that directory is exposed in the "New macro"
dropdown after the bundled templates. Filenames starting with an
Expand Down
2 changes: 1 addition & 1 deletion datalab/gui/panel/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
- :mod:`datalab.gui.objectview`: Widgets to display object (signal/image) trees
- :mod:`datalab.gui.plothandler`: `PlotPy` items for representing signals and images
- :mod:`datalab.gui.processor`: Processor (computation)
- :mod:`datalab.gui.panel.roieditor`: ROI editor
- :mod:`datalab.gui.roieditor`: ROI editor

The Macro Panel is used to display and run macros. It relies on the
:mod:`datalab.gui.macroeditor` module to handle the macro edition and execution.
Expand Down
6 changes: 4 additions & 2 deletions datalab/gui/processor/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,13 @@

* - ``compute_n_to_1``
- n objects ➝ 1 object
- n ➝ 1<br>n ➝ n (pairwise mode)
- | n ➝ 1
| n ➝ n (pairwise mode)

* - ``compute_2_to_1``
- 1 object + 1 operand ➝ 1 object
- k + 1 ➝ k<br>n + n ➝ n (pairwise mode)
- | k + 1 ➝ k
| n + n ➝ n (pairwise mode)

These methods are for internal or advanced use (e.g. plugin or macro authors) and
will evolve without backward compatibility guarantees.
Expand Down
14 changes: 13 additions & 1 deletion datalab/plugins/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,19 @@ class PluginCapability(str, enum.Enum):

@dataclasses.dataclass
class PluginInfo:
"""Plugin info"""
"""Plugin info

Attributes:
name: Plugin display name
version: Plugin version
description: Plugin description
icon: Plugin icon: ``package:relative/path`` resource, ``module:filename``
image registered with guidata, or DataLab icon file name
id: Stable, namespaced plugin ID (e.g. ``"org.example.my-plugin"``)
capabilities: Plugin capabilities (:class:`PluginCapability` values)
documentation_url: HTTP or HTTPS URL of the plugin documentation, opened
by the **Documentation** action of the **Applications** panel
"""

name: str = None
version: str = "0.0.0"
Expand Down
4 changes: 3 additions & 1 deletion datalab/tests/features/plugins/templates/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Template files use the `.py.template` extension so that linters (Ruff, Pylint)
skip them – they contain `{placeholders}` that are not valid Python.

- **plugin_valid.py.template**: Basic valid plugin template with actions for both signal and image panels
- **plugin_owned_processing.py.template**: Plugin registering an owned processing feature in `register_computations()`
- **plugin_nested_menus.py.template**: Plugin with nested submenus (3 levels deep)
- **plugin_with_dialogs.py.template**: Plugin demonstrating dialog methods (show_warning, show_error, etc.)
- **plugin_many_actions.py.template**: Plugin with multiple actions in a dropdown menu
Expand Down Expand Up @@ -77,7 +78,7 @@ When creating a new template:
1. Use `{placeholder}` syntax for values that will be replaced
2. Avoid f-strings with placeholders (use variables instead)
3. Document required placeholders in template comments
4. Add corresponding test in `test_plugins.py`
4. Add corresponding test in `plugins_app_test.py`
5. Update this README

## Directory Structure
Expand All @@ -86,6 +87,7 @@ When creating a new template:
datalab/tests/features/plugins/templates/
├── README.md # This file
├── plugin_valid.py.template # Standard valid plugin
├── plugin_owned_processing.py.template # Owned processing feature
├── plugin_nested_menus.py.template # Nested submenus
├── plugin_with_dialogs.py.template # Dialog methods
├── plugin_many_actions.py.template # Many dropdown actions
Expand Down
6 changes: 3 additions & 3 deletions datalab/webapi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,16 @@
By default, the API:

- Binds to localhost only (127.0.0.1)
- Requires a bearer token for authentication
- Requires a bearer token for authentication, except for requests from the local
machine while the "Web API localhost bypass" setting is enabled (default)
- Token is generated at startup and displayed in the UI

Usage
-----

Enable the Web API via:

- **UI**: Tools → Web API → Start
- **CLI**: ``datalab --webapi``
- **UI**: File → Web API → Start Web API Server
- **Environment**: ``DATALAB_WEBAPI_ENABLED=1``

See Also
Expand Down
2 changes: 1 addition & 1 deletion doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ def exclude_api_from_gettext(app):
html_show_sourcelink = False
templates_path = ["_templates"]
if "language=fr" in sys.argv:
ann = "DataLab a été présenté à <a href='https://pretalx.com/euroscipy-2026/talk/E3X9EX/'>EuroSciPy 2026</a> 🇵🇱 et à <a href='https://www.youtube.com/watch?v=0D4ffBJIc5Q&list=PLJjbbmRgu6RoVze2tajiPe3zJB5muBcuC'>OSXP 2025</a> 🇫🇷 🚀 — <a href='https://datalab-platform.com/fr/outreach/index.html'>En savoir plus</a>" # noqa: E501
ann = "DataLab a été présenté à <a href='https://pretalx.com/euroscipy-2026/talk/E3X9EX/'>EuroSciPy 2026</a> 🇵🇱 et à <a href='https://datalab-platform.com/fr/outreach/osxp2025.html'>OSXP 2025</a> 🇫🇷 🚀 — <a href='https://datalab-platform.com/fr/outreach/index.html'>En savoir plus</a>" # noqa: E501
catalog_link_name = "Catalogue de plugins"
else:
ann = "DataLab has been presented at <a href='https://pretalx.com/euroscipy-2026/talk/E3X9EX/'>EuroSciPy 2026</a> 🇵🇱 and at <a href='https://datalab-platform.com/en/outreach/osxp2025.html'>OSXP 2025</a> 🇫🇷 🚀 — <a href='https://datalab-platform.com/en/outreach/index.html'>Learn more</a>" # noqa: E501
Expand Down
1 change: 1 addition & 0 deletions doc/contributing/dependencies.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Among the optional dependencies, we have the following groups:

- `qt`: Qt-based graphical user interface (currently, PyQt5).
- `opencv`: computer vision tasks requiring OpenCV.
- `exe`: building the stand-alone Windows executable with PyInstaller (pinned version), including OpenCV and PyQt5.
- `dev`: development and testing (linters, formatters, etc.).
- `doc`: building the documentation (Sphinx, etc.).
- `test`: running the tests (pytest, etc.).
Expand Down
21 changes: 13 additions & 8 deletions doc/contributing/environment.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,11 @@ Installing all required packages :
ℹ️ See [Installation](https://datalab-platform.com/en/intro/installation.html)
for more details on reference Python and Qt versions.

⚠️ If you are contributing to DataLab's processing features, you will need to work on both DataLab's main repository and sigima's repository. To install `sigima` in editable mode, use the following command:
⚠️ DataLab relies on its sibling repositories [Sigima](https://github.com/DataLab-Platform/Sigima) (processing features), [SigimaX](https://github.com/DataLab-Platform/SigimaX) (application framework) and [DataLab-Capsule](https://github.com/DataLab-Platform/DataLab-Capsule) (workspace capsules). If your contribution needs unreleased changes of these repositories (e.g. a processing feature, implemented in Sigima), you will need to work on them too. Either install them in editable mode:

pip install -e ../sigima # Adjust the path to your local sigima repository
pip install -e ../Sigima -e ../SigimaX -e ../DataLab-Capsule # Adjust the paths to your local repositories

or add them to the `PYTHONPATH` variable of the `.env` file (see below), e.g. `PYTHONPATH=.;../Sigima;../SigimaX;../DataLab-Capsule/src`.

If you are using [WinPython](https://winpython.github.io/), thank you for supporting
the scientific open-source Python community!
Expand All @@ -72,6 +74,7 @@ The following table lists the currently officially used Python distributions:
| 3.11 | OK | 3.11.5.0 |
| 3.12 | OK | 3.12.3.0 |
| 3.13 | OK | 3.13.2.0 |
| 3.14 | OK | 3.14.5.0 |

⚠ We strongly recommend using the `.dot` versions of WinPython which are lightweight
and can be customized to your needs (using `pip install -r requirements.txt`).
Expand Down Expand Up @@ -121,7 +124,7 @@ Windows installer

The official Windows executable and MSI installer are built by the GitHub CI release pipeline. The Python version embedded in the standalone application shipped to end users is defined by the `python-version` input default of the reusable build workflow (`.github/workflows/_build.yml`), consumed by its `build-msi` job; the release workflows do not override it. That workflow is the single source of truth — refer to it for the exact version currently in use.

The Windows installer is built using [WiX Toolset](https://wixtoolset.org/) V4.0.5.
The Windows installer is built using [WiX Toolset](https://wixtoolset.org/) V4 (the CI release pipeline installs the latest 4.x version, with the WiX UI extension V4.0.5).
Using the WiX Toolset requires [.NET SDK](https://dotnet.microsoft.com/download/dotnet/) V6.0 minimum.

You may install .NET SDK using `winget`:
Expand All @@ -131,16 +134,18 @@ You may install .NET SDK using `winget`:
Once .NET SDK is installed, the WiX Toolset can be installed and configured using the
following commands:

dotnet tool install --global wix --version 4.0.5
wix extension add WixToolset.UI.wixext/4.0.5
dotnet tool install --global wix --version 4.*
wix extension add -g WixToolset.UI.wixext/4.0.5

First, you need to generate the installer script from a generic template:
First, you need to generate the installer script from a generic template (replace `X.Y.Z` by the version of DataLab, e.g. `1.4.0`):

python wix/makewxs.py
python wix/makewxs.py DataLab X.Y.Z

Building the installer is done using the following command:

wix build .\wix\DataLab.wxs -ext WixToolset.UI.wixext
wix build wix\DataLab-X.Y.Z.wxs -ext WixToolset.UI.wixext

Alternatively, `scripts\build_installer.bat` (Visual Studio Code task "📦 Create installer") runs both commands for the current version of DataLab.

Release smoke test
------------------
Expand Down
Loading
Loading