Start by forking this main repository that will house all your plugins.
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.
-
Ensure you have docker installed. Docker nowadays comes with
docker composebuilt in. Prior, you need to install the stand-alone docker-compose. -
Install uv (v0.5.14 and above).
uvis required to manage your development environment. It's recommended to use the standalone installer or perform a global installation. (brew install uvon macOS ordnf install uvon Fedora). -
Install node.js (v20) and yarn(v1.22). We will use it to setup the GUI.
-
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 Windows Subsystem for Linux (WSL) to run the project.
-
Clone the forked repository.
git clone https://github.com/<your-username>/nomad-distro-dev.git cd nomad-distro-dev
-
Run the docker containers with
docker composein detached (--detach or -d) mode.docker compose up -d
To shutdown the containers:
docker compose down
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.
-
Update submodules
This loads the
nomad-labpackage which is already listed as a submodule.git submodule update --init --recursive
Tip
To get more information on how git submodules are used to structure bigger software projects, read the this Github blog entry on this topic.
-
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
-
Modify
pyproject.tomlTo ensure
uvrecognizes the local plugins (a local copy of your plugin repository available inpackages/directory), we need to make some modifications in thepyproject.toml. These include adding the plugin package to[project.dependencies]and[tool.uv.sources]tables. The packages listed under[tool.uv.sources]are loaded byuvusing the local code directory made available underpackages/with the previous step. This list will contain all the plugins that we need to actively develop in this environment.If a new plugin is not listed under
[project.dependencies], we need to first add it as a dependency. After adding the dependencies, update the[tool.uv.sources]section in yourpyproject.tomlfile to reflect the new plugins.There are two ways of adding to these two lists:
a) You can use
uv addwhich adds the dependency and the source inpyproject.tomland sets up the environment. Adding multiple plugins should be done in a single command:uv add packages/nomad-measurements packages/PLUGIN_B packages/PLUGIN_C
In this example, we're just adding one:
uv add packages/nomad-measurements
b) You can modify the
pyproject.tomlfile 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 fornomad-parser-plugins-electronics.[tool.uv.sources] ... nomad-parser-plugins-electronic = { workspace = true }
Note
You can also use uv to install a specific branch of the plugin without adding a submodule locally.
uv add https://github.com/FAIRmat-NFDI/nomad-measurements.git --branch <specific-branch-name>This command will not include the plugin in the packages/ folder, and hence this plugin will not be editable.
A complete list of plugins maintained by FAIRmat-NFDI can by found in the overview page of the FAIRmat-NFDI organisation.
After the initial setup, here’s how to manage your daily development tasks.
-
Update the environment (This step installs the necessary dependencies):
uv run poe setup
As part of the setup command, a
nomad.yamlconfig file will be created, this file is used to configure nomad. It will be placed in the top-level directory of your repository, where all commands are executed from.For more information on configuration options, refer to the detailed nomad configuration docs.
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.
-
Running
nomadapi app (equivalent to runninguv run nomad admin run appworker).uv run poe start
-
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.
- [Optional] Run the docs server (only if you wish to run the documentation server):
Add the nomad-docs repository as a submodule (if you have added it as a submodule already, skip this step):
git submodule add https://github.com/FAIRmat-NFDI/nomad-docs.git packages/nomad-docsJust like adding a new plugin, use uv to add nomad-docs to the environment:
uv add packages/nomad-docsAt this moment, you can commit the changes made to your nomad-dev-distro.
Now, everytime you want to start the docs server, run the following:
uv run poe docs-
[Optional] Run the remote tools hub server (only if you wish to use the remote tools hub):
uv run poe hub
-
Running tests
To run tests across the project, use the
uv runcommand to executepytestin 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 run --exact --all-extras --package plugin_a --directory packages/plugin_a pytest
-
Linting & code formatting
To check for linting issues using
ruff, run the following command:uv run poe lint
You can invoke
ruffseparately usinguv run rufftoo. -
Adding new plugins
To add a new package, follow setup guide and add it into the
packages/directory and ensure it's listed inpyproject.tomlunder[tool.uv.sources]. Then, install it by running:uv sync
-
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]inpyproject.tomlto stopuvfrom using the local plugin repository.Additionally, if you want to remove the plugin from being a dependency of your NOMAD installation, you can use
uvto entirely remove it:uv remove <plugin-name>
-
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-
Generating GUI test artifacts and nomad requirements files
uv run poe gen-gui-test-artifacts uv run poe gen-nomad-lock
-
Keeping Up-to-Date
To pull updates from the main repository and submodules, run:
git pull --recurse-submodules
Afterward, sync your environment:
uv sync
Note
The nomad instance will be available on http://localhost:3000/nomad-oasis/gui, and expects to find the nomad API on localhost:8000, and the remotes tool hub on localhost:9000. If you are running the instance on a remote server, make sure to forward these ports locally.
As an alternative way to port forwarding, the backend URL for the GUI can be configured too. For that, the REACT_APP_BACKEND_URL in packages/nomad-FAIR/gui/.env.development can be modified to the appropriate API url.
To keep your fork up to date with the latest changes from the original repository (upstream), follow these steps:
-
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
-
Fetch the Latest Changes from upstream
git fetch upstream
-
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.
-
Push the Updates to Your Fork
After merging, push the updated branch to your fork on GitHub:
git push origin main
-
Failed to install
phonopy.uv venv -p 3.12 uv pip install 'numpy>=1.25' uv pip install 'phonopy==2.11.0' --no-build-isolation
-
Failed to install
pycifrw.The error usually indicates that clang was missing.
error: command 'clang'. Installingclangshould fix this issue.