Contributing

Ribasim-NL welcomes contributions.

Setting up the developer environment

Clone Ribasim

In order to have the Ribasim-NL repository locally available, you can clone it with Git. Git can be installed from git-scm.com. Once installed, run the following command at a directory of your choice:

In order to have the Ribasim repository locally available, run the following command at a directory of your choice:

git clone https://github.com/Deltares/Ribasim-NL.git

To continue with the following steps, make the root of the repository your working directory by running

cd Ribasim-NL

Setting up uv

First, set up uv as described in the uv documentation.

We require at least uv version v0.9.3, but generally recommend the latest release. Check the version with uv --version, update with uv self update.

Then set up the environment by running the following command.

uv sync

This command automatically installs all required Python packages for development. These will not conflict with any pre-installed applications, as uv creates an isolated virtual environment. You can run Python commands using uv run python or activate the environment with source .venv/bin/activate (Linux/macOS) or .venv\Scripts\activate (Windows).

The first time you open the Ribasim-NL repo in Visual Studio Code you need to tell it where it can find the Python interpreter. Open the command box with Ctrl+Shift+P (Cmd+Shift+P on macOS) and run Python: Select Interpreter. Select the Python interpreter in the .venv folder that uv created. Unless the setting python.terminal.activateEnvironment is disabled, it will already activate the environment in your terminal.

If you encounter issues related to uv dependencies, it might help to clean your uv environment with uv clean, followed by uv sync.

Install pre-commit git hook scripts

Pre-commit is part of the uv environment, hence you can run:

uv run pre-commit install

For more information see the pre-commit documentation.

Co-development with Ribasim

Ribasim-NL pins to a specific Ribasim version in the pyproject.toml. Generally this will be the latest release. During development sometimes you may want to test out the latest unreleased development version of Ribasim.

To do so, open pyproject.toml in your editor. Find the [tool.uv.sources] section and uncomment or add the git source like below:

[tool.uv.sources]
ribasim = { git = "https://github.com/Deltares/Ribasim", branch = "main", subdirectory = "python/ribasim" }

You can change the branch name if needed, or use a specific commit with for example rev = "0075d4a".

If you are making changes to the Ribasim repository yourself, it will be more convenient to point to a local clone rather than GitHub. This can be done using this syntax:

[tool.uv.sources]
ribasim = { path = "../Ribasim/python/ribasim", editable = true }

This path will work if you clone Ribasim next to Ribasim-NL.

After you are done modifying pyproject.toml, you can run uv sync to ensure the dependencies are installed.

For Ribasim developer documentation see ribasim.org/dev.

Environment variables

The Ribasim-NL code downloads from and uploads to cloud storage. The password to access the cloud storage, and local directory it interacts with, both need to be configured. To be able to run the Ribasim core, point RIBASIM_HOME to a Ribasim-NL specific install, to avoid interaction with possible other Ribasim projects.

In the root of the repository is a .env.default file that can serve as a template to copy to .env. The .env file is gitignored because it is different per developer, and to avoid leaking the password.

Here is an example for a filled in .env file:

RIBASIM_NL_CLOUD_PASS='your_password_here'
RIBASIM_NL_DATA_DIR='data'
RIBASIM_HOME='bin/ribasim'  # make sure to use single quotes
OVERWRITE_FILES_FROM_CLOUD='true'

These values will be applied using pydantic-settings. If you prefer to set these environment variables in your OS or terminal that will also work.

OVERWRITE_FILES_FROM_CLOUD is optional, and true by default. When using cloud.synchronize or cloud.download_content, this will determine if local files will be overwritten if the overwrite keyword argument is not explicitly passed. Whilst updating datasets locally, you can set this to false to ensure your modifications can be tested and will not be lost. After these edits are done, you can upload the new dataset, and set it back to true.

Type checking

We use Pyrefly for static type checking. Pyrefly is configured in the [tool.pyrefly] section of pyproject.toml.

Running Pyrefly

To check for type errors, run:

uv run pyrefly check

This is also run in CI via the pyrefly job in .github/workflows/python_lint.yml.

Baseline file

Existing type errors are stored in a baseline.json file. Pyrefly’s baseline feature suppresses these known errors and only reports new errors. This way, pyrefly check passes cleanly without requiring ignore comments on every line.

The baseline is configured in pyproject.toml:

[tool.pyrefly]
baseline = "baseline.json"

Updating the baseline

After fixing existing type errors, regenerate the baseline to remove the fixed entries:

uv run pyrefly check --update-baseline

If you introduce code that triggers new errors (e.g. from incomplete stubs) that cannot be reasonably fixed, you can add them to the baseline by running the same command. Prefer fixing the error or adding a targeted # pyrefly: ignore[error-code] comment when possible.

Suppressing individual errors

For specific lines where the type checker is wrong, use a targeted ignore comment:

x = some_expression  # pyrefly: ignore[error-code]

For lines that would exceed 120 characters with the comment appended, place the comment on the line above:

# pyrefly: ignore[error-code]
x = some_very_long_expression_that_would_be_too_long_with_an_inline_comment