Skip to content

Add a "New plugin" wizard to generate a ready-to-use plugin skeleton #377

Open

Description

@ThomasMalletCodra

Context

DataLab already includes the installed datalab-plugin create command, implemented in datalab/plugins/generator.py and documented in the plugin guide. It supports interactive or scripted creation of a layered, installable plugin project with identity metadata, a datalab.plugins entry point, core/workflow/adapters boundaries, an optional sample signal or image processing, tests, documentation, and protection against overwriting an existing destination.

The missing feature is an integrated graphical creation workflow, not code generation from scratch. The existing CLI does not provide the proposed wizard, all the skeleton options below, immediate loading, configuration updates, or external-editor integration.

For users following the single-file plugin workflow rather than creating and installing a package, the manual steps are:

  1. find the plugin directory (or configure an extra one),
  2. copy one of the example plugins from plugins/examples/,
  3. rename the file with the mandatory datalab_ prefix (otherwise the plugin is silently ignored by the discovery mechanism),
  4. adapt the class, PLUGIN_INFO and actions by hand,
  5. reload plugins.

Related issues:

This issue goes one step further than #26 and complements the existing CLI. From within DataLab, users should be able to generate a working, ready-to-edit plugin skeleton tailored to their use case, write it to the right place and load it immediately.

The initial scope remains the lightweight single-file workflow described below. The existing installable-project workflow is not replaced, and adding package installation to the wizard is not required. The implementation must reuse and, where necessary, extend the existing generator's reusable logic rather than introduce a second independent generation engine. The GUI should call a Python API, not launch the CLI or its interactive prompts.

Proposed feature

A new Plugins > New plugin... menu entry opens a wizard, built on the existing sigimax.widgets.wizard.Wizard.

Wizard pages

  1. Identity: plugin name, description, author, version.
  2. Plugin type:
    • Empty plugin (menu + action)
    • Processing (1 object → 1 object) or/and Analysis (1 object → results/metadata) (methods/actions list -> see options)
    • File format (read and write)
  3. Options:
    • Target: signal, image, or both
    • Add sub action menu list (defined by python methods) auto generated from a populated forms (number, name, label)
    • Add a parameter set (guidata DataSet) edited in a dialog before running the action
    • Add a blank custom Qt dialog (QDialog with OK/Cancel buttons only)
  4. Destination & summary:
    • Target directory
    • Generated file name ( datalab_ prefix enforced)
    • Load plugin now (checked by default)
    • Open in external editor (checked by default)

Code generation

  • Reuse datalab/plugins/generator.py as the owning generation module, extracting or extending reusable helpers as needed to support both the existing installable-project output and the wizard's single-file output. Share identity validation and skeleton rendering where the output contracts overlap; keep output-specific constraints explicit.
  • Follow the existing standard-library rendering approach; string.Template may be used where useful, but replacing the existing renderer is not a requirement. No new templating dependency is needed.
  • Preserve the existing datalab-plugin create command and its layered installable-project output. Declaring a capability in the CLI is not equivalent to generating a complete analysis or file-format skeleton; the missing templates below remain part of this issue.
  • Templates are composable blocks (type × target × options), not one full template per combination.
  • Every generated skeleton must be valid and loadable as-is, even if its actions do nothing yet.
  • The file-format template is a minimal reader/writer that relies on the same standard base classes as plugins/examples/datalab_example_imageformat.py.

Validation and configuration handling

  • The plugin name is converted to a valid Python identifier, and the datalab_ file prefix is enforced.
  • An existing file or plugin name is detected: generation is refused, or overwriting is explicitly confirmed by the user.
  • If the plugin system is disabled (plugins_enabled = False), the wizard warns the user (or disabled in menu plugin actions)
  • If an explicit list of enabled plugins is configured (plugins_enabled_list is not None), the new plugin is added to it so that it is actually loaded.
  • If the target directory is not yet known to DataLab, it is added to plugins_path_list and the user is informed.

After generation

  • The plugin is loaded immediately through the existing hot-reload mechanism, so its menu entry appears right away.
  • The generated file is opened in the external editor configured in DataLab settings (external_editor_path / external_editor_args), at the create_actions() line. This reuses the mechanism behind "go to error" in the console. The editor-launching logic is extracted from go_to_error() into a small reusable helper in SigimaX.
  • If the editor cannot be launched, the containing folder is opened instead.

Impacted repositories

  • DataLab: menu action, wizard subclass, reuse and extension of datalab/plugins/generator.py, shared templates/helpers with explicit single-file and installable-project output contracts, configuration updates, tests, documentation (EN/FR), release notes.
  • SigimaX: extraction of a reusable "open file in external editor" helper from go_to_error(). No behavior change for the console.

Acceptance criteria

  • Plugins > New plugin... opens the wizard. Its entry point is disabled, or shows a warning, when plugins are disabled.
  • The wizard uses a reusable Python API in the existing generation module, with shared logic where applicable rather than a parallel independent generator.
  • Existing datalab-plugin create behavior, layered project structure, entry point, and overwrite protection remain covered by regression tests.
  • All combinations of type × target × options generate a module that imports without error and registers in PluginRegistry (parametrized test).
  • The generated file always uses the datalab_ prefix and never silently overwrites an existing file.
  • After generation, the plugin is loaded and visible in the Plugins menu without restarting DataLab.
  • plugins_path_list and plugins_enabled_list are updated when required.
  • The generated file opens in the configured external editor, with a fallback to opening the folder.
  • go_to_error() behavior in the console is unchanged.
  • UI strings are translatable, and French translations are provided.
  • The plugin documentation page gets a text section describing the wizard (EN + FR), explaining its single-file workflow alongside the existing datalab-plugin create installable-project workflow, and release notes are updated.

Out of scope (possible future enhancements)

  • Elaborate custom Qt interfaces beyond a blank OK/Cancel dialog.
  • Generating or installing a distributable plugin package from the wizard (pyproject.toml, tests, README). Package generation already exists in datalab-plugin create and must remain supported; exposing that workflow in the GUI is a possible future enhancement.
  • Field-by-field definition of the parameter set inside the wizard.
  • Screenshots in the documentation.

Activity

  1. added this to the V1.5.0 milestone on Oct 6, 2026
  2. PierreRaybaut commented on Oct 21, 2026

    @PierreRaybaut
    Contributor

    Heads-up on a related change in the generator: #413, implemented by #414 (ready for review, not merged).

    datalab-plugin create now creates a single-file plugin by default (a datalab_<name>.py file written to the user plugin directory, after asking only for the plugin name and description). The layered installable project is unchanged and created with --project, so the "preserve the existing datalab-plugin create command and its layered installable-project output" requirement of this issue is met through that option.

    Foundation that the wizard can reuse, in datalab/plugins/generator.py:

    • render_single_file_plugin(project) -> str and create_single_file_plugin(project) -> Path, usable without the CLI, on the existing PluginProject configuration;
    • get_default_plugin_folder(), which returns DataLab's user plugin directory;
    • the datalab_ prefix enforced and no overwrite of an existing file (FileExistsError);
    • user values written as readable Python string literals (accents kept, quotes as Ruff formats them), and accents removed from the derived module and class names;
    • rendering split into fragments: imports, sample processing (a NumPy function to edit, applied by a @computation_function() and registered with register_1_to_1), menu action, plugin declaration.

    Still in the scope of this issue: the wizard and its menu entry, the composable templates (analysis, file format, parameter sets, dialogs, signal and image), author and version fields, plugins_path_list / plugins_enabled_list updates, immediate loading and the external editor.

    Note for the templates: a processing must be registered as a @computation_function(). Registering a Wrap1to1Func instance directly is refused by DataLab, which is also why the documented example plugins/examples/datalab_custom_func.py currently fails.

  3. PierreRaybaut commented on Oct 21, 2026

    @PierreRaybaut
    Contributor

    Correction to my previous comment: since #416 (fixes #415) is merged, 1-to-1 features also accept a NumPy function wrapped with Sigima's Wrap1to1Func (sigima.proc.signal or sigima.proc.image), as the documented example plugins/examples/datalab_custom_func.py does. The note saying that a processing must be a @computation_function() no longer applies: a decorated computation function remains needed for other patterns, or for features with parameters.

    The single-file plugin generated by #414 now registers Wrap1to1Func(sample_processing) directly, without the decorated compute_sample_processing function.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions