/dev_distro

Primary LanguagePythonApache License 2.0Apache-2.0

Start by forking main repository (/FAIRmat-NDFI/nomad-distro-dev) that will house all your plugins.

NOMAD Dev Distribution

Benefits

  • One-step installations: Install everything at once with editable mode. Since all packages are installed in editable mode, changes you make to the code are immediately reflected. Edit your code and rerun tests or the application as needed, without needing to reinstall the packages.
  • Centralized codebase: Easier navigation and searching across projects.
  • Better editor support: Improved autocompletion and refactoring.
  • Consistent tooling: Shared linting, testing, and formatting.
  • Flexible plugin management: If you're developing plugins for different deployments with varying requirements, you can easily create different branches for each deployment and configure which plugins to use in the specific branch for that deployment.

Below are instructions for how to create a dev environment for developing nomad-lab and its plugins.

Basic infra

  1. Ensure you have docker installed. Docker nowadays comes with docker compose built in. Prior, you needed to install the stand-alone docker-compose.

  2. Install uv. uv is required to manage your development environment. It's recommended to use the standalone installer or perform a global installation. (brew install uv on macOS or dnf install uv on Fedora).

  3. Install node.js (v20) and yarn(v1.22). We will use it to setup the GUI.

  4. For Windows users, nomad-lab processing doesn't work natively on the platform. We highly recommend using the Devcontainer plugin in VSCode to run the repository within a container, or alternatively, using GitHub Codespaces to run the project.

  5. Clone the forked repository.

    git clone https://github.com/<your-username>/nomad-distro-dev.git
    cd nomad-distro-dev
  6. Run the docker containers with docker compose in detached (--detach or -d) mode.

    docker compose up -d

    To shutdown the containers:

    docker compose down

Developing nomad + plugins locally.

This guide explains how to set up a streamlined development environment for nomad-lab and its plugins using uv workspaces. This approach eliminates the need for multiple pip install commands by leveraging a monorepo and a single installation step.

In this example, we'll set up the development environment for a developer working on the following plugins: nomad-parser-plugins-electronic and nomad-measurements. The first plugin already comes as a dependency in this dev distribution. On the contrary, the second plugin is not listed as a dependency. In the following, we take a look at how to setup the environment in these two situations.

Step-by-Step Setup

  1. Update submodules

    This loads the nomad-lab package which is already listed as a submodule.

    git submodule update --init --recursive
  2. Add local plugins

    Assuming that you already have a git repo for your plugins, add them to the packages/ directory as submodules. In case, you are looking to create a plugin repo from scratch, consider using our plugin template: nomad-plugin-template.

    git submodule add https://github.com/<package_name>.git packages/<package_name>

    Repeat for all the plugin packages you want to add and develop. For our example:

    git submodule add https://github.com/nomad-coe/electronic-parsers.git packages/nomad-parser-plugins-electronic
    
    git submodule add https://github.com/FAIRmat-NFDI/nomad-measurements.git packages/nomad-measurements
  3. Modify pyproject.toml

    To ensure uv recognizes the local plugins (a local copy of your plugin repository available in packages/ directory), we need to make some modifications in the pyproject.toml. These include adding the plugin package to [project.dependencies] and [tool.uv.sources] tables. For the packages listed under [tool.uv.sources], uv uses the local code directory made available under packages/ with the previous step.

    To add a new plugin not listed under [project.dependencies], you must first add it as a dependency. After adding the dependencies, update the [tool.uv.sources] section in your pyproject.toml file to reflect the new plugins.

    You can use uv add which adds the dependency and the source in pyproject.toml and sets up the environment:

    uv add nomad-measurements

Note

You can also use uv to install a specific branch of the plugin submodule.

uv add https://github.com/FAIRmat-NFDI/nomad-measurements.git --branch <specific-branch-name>

Or you can modify the pyproject.toml file manually:

[project]
dependencies = [
...
"nomad-measurements",
]

[tool.uv.sources]
...
nomad-measurements = { workspace = true }

Some of the plugins are already listed under [project.dependencies]. If you want to develop one of them, you have to add them under [tool.uv.sources]. We do this for nomad-parser-plugins-electronics.

[tool.uv.sources]
...
nomad-parser-plugins-electronic = { workspace = true }
  1. Create a nomad.yaml file.

This file is used to configure nomad. For more information on configuration options, refer to the detailed nomad configuration docs.

Below is the default configuration for a development environment, using the test realm:

keycloak:
  realm_name: "fairdi_nomad_test"

Day-to-Day Development

After the initial setup, here’s how to manage your daily development tasks.

  1. Update the environment (This step updates the submodules and installs the necessary dependencies):

    uv run poe setup

Note

uv sync and uv run automatically manages the virtual environment for you. There's no need to manually create or activate a venv. Any uv run commands will automatically use the correct environment by default. Read more about uv commands to manage the dependencies here.

  1. Running nomad api app (equivalent to running uv run nomad admin run appworker).

    uv run poe start
  2. Start NOMAD GUI

    uv run poe gui start

Tip

uv run poe gui maps to yarn run, so here you can replace start with commands like test, build, etc.

  1. Run the docs server (optional: only if you wish to run the documentation server):

    uv run poe docs
  2. Running tests

    To run tests across the project, use the uv run command to execute pytest in the relevant directory. For instance:

    uv run --directory packages/package_name pytest

    This allows you to run tests for a specific parser or package. For running tests across all packages, simply repeat the command for each directory.

Tip

To run tests for a specific package in an isolated venv use: uv sync --all-extras --package plugin_a && uv run --package plugin_a --directory packages/plugin_a pytest

  1. Linting & code formatting

    To check for linting issues using ruff, run the following command:

    uv run poe lint

    You can invoke ruff separately using uv run ruff too.

  2. Adding new plugins

    To add a new package, follow setup guide and add it into the packages/ directory and ensure it's listed in pyproject.toml under [tool.uv.sources]. Then, install it by running:

    uv sync
  3. Removing an existing plugin

    To remove an existing plugin from the workspace in packages/ directory, do the following and commit:

    git rm <path-to-submodule>

    Then you can remove the plugin from [tool.uv.sources] in pyproject.toml to stop uv from using the local plugin repository.

    Additionally, if you want to remove the plugin from being a dependency of your NOMAD installation, you can use uv to entirely remove it:

    uv remove <plugin-name>
  4. Modifying dependencies in packages.

    uv add --package <PACKAGE_NAME> <DEPENDENCY_NAME>

    For example:

    uv add --package nomad-measurements "pandas>=2.0"
    uv remove --package nomad-lab numpy
  5. Generating gui test artifacts and nomad requirements files

    uv run poe gen-gui-test-artifacts
    uv run poe gen-nomad-lock
  6. Keeping Up-to-Date

    To pull updates from the main repository and submodules, run:

    git pull --recurse-submodules

    Afterward, sync your environment:

    uv sync

Updating the fork

To keep your fork up to date with the latest changes from the original repository (upstream), follow these steps:

  1. Add the upstream Remote

    If you haven't already, add the original repository as upstream:

    git remote add upstream https://github.com/FAIRmat-NFDI/nomad-distro-dev.git
  2. Fetch the Latest Changes from upstream

    Fetch the latest commits from the upstream repository:

    git fetch upstream
  3. Merge upstream/main into Your Local Branch

    Switch to the local branch (e.g., main) you want to update, and merge the changes from upstream/main:

    git checkout main
    git merge upstream/main

    Resolve any merge conflicts if necessary, and commit the merge.

  4. Push the Updates to Your Fork

    After merging, push the updated branch to your fork on GitHub:

    git push origin main