Versioned Python scripts

BornAgain’s Python API is not yet stable: a script written for one major release may misbehave or fail under another one. Therefore every script should state which BornAgain version it is written for.

Runtime guard

Scripts shipped with BornAgain check the installed version right after the import:

import bornagain as ba
ba.require_versions("bornagain>=25,<26")

ba.require_versions accepts any number of PEP 508 requirement strings, e.g. "bornagain>=25,<26", "python>=3.10", "numpy>=1.24". If a script uses Python or package features beyond BornAgain’s baseline, add these requirements explicitly. Formatting does not matter; this can be written on one line:

import bornagain as ba
ba.require_versions("bornagain>=25,<26", "python>=3.11", "numpy>=1.24", "scipy>=1.10")

or split over several lines:

import bornagain as ba
ba.require_versions(
    "bornagain>=25,<26",
    "python>=3.11",
    "numpy>=1.24",
    "scipy>=1.10",
)

If a requirement is not met, the script stops immediately with an ImportError that names the installed and the required version, instead of failing later in some obscure way. We recommend the same guard for any user script.

One virtual environment per major release

The guard detects a version mismatch, but does not fix it. To run scripts that require different BornAgain versions on one computer, install each major version in a virtual environment of its own:

python -m venv ~/.venvs/ba24
~/.venvs/ba24/bin/pip install "bornagain==24.*"

python -m venv ~/.venvs/ba25
~/.venvs/ba25/bin/pip install "bornagain==25.*"

Run a script with the matching interpreter, no activation needed:

~/.venvs/ba24/bin/python my_old_script.py

Virtual environments are fully isolated and trivially reversible: deleting the directory removes the installation entirely. Avoid pip install into the system Python or pip install --user, which allow only one BornAgain version system-wide.

Self-installing scripts with uv

Scripts shipped with BornAgain also declare their requirements in a PEP 723 comment block:

# /// script
# requires-python = ">=3.10"
# dependencies = ["bornagain>=25,<26"]
# ///

Users of uv then get a matching environment created on the fly, without any manual setup:

uv run my_script.py