Contributing
Contributions to OpenPKPD are welcome. This page describes how to set up a development environment, run the test suite, and submit a pull request.
Development setup
Prerequisites
Python 3.12+ and uv
Rust toolchain — required to compile the
openpkpd._coreextension. Install once with:curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
On Windows, download and run
rustup-init.exefrom rustup.rs. The Rust toolchain is needed at build time only — end-users who install a pre-built wheel from PyPI do not need it.
Setup
git clone https://github.com/your-org/OpenPKPD.git
cd OpenPKPD
# Install all extras including dev tools
uv sync --all-extras
# Or, for the symbolic analytical-kernel test path specifically
uv sync --extra dev --extra symbolic
# Compile and install the Rust extension in-place
just build-core
# Verify
uv run pytest -q
just prewarm-symbolic-caches
Note: If you skip
just build-core, the package will still import and all tests will pass — the pure-Python fallback is used automatically. The compiled extension only affects runtime performance of the log-likelihood inner loop.
just workflow and platform support
The repository includes a justfile for common contributor workflows. The
recipes are intended to work on macOS, Linux, and Windows.
Recipes now select their own
uvextras where needed, so commands like docs, GUI, plotting examples, and cluster examples do not rely on a pre-synced all-extras environment.Shell-heavy operations have been moved into Python helpers under
scripts/just/to keep behavior as consistent as possible across platforms.
Typical usage:
just run-tests-unit
just prewarm-symbolic-caches
just lint
just build-docs-html
just run-example 01
Remaining external prerequisites depend on the recipe:
build-core/build-wheelrequire the Rust toolchain (rustup)build-core-native-cvodesalso requires the Rust toolchain and enables the optional native CVODES pathinstall-hooksrequiresgitbuild-docs-pdfrequires a working LaTeX installationwatch-docsand the*-and-openrecipes require browser/open support on the hostrun-guirequires a working desktop/Qt environment
For the current native CVODES path, the development workflow is:
just build-core-native-cvodes
just smoke-native-cvodes
With that recipe, development mode allows the package to preload SUNDIALS shared libraries from both:
local Cargo build outputs
package-adjacent library directories such as
openpkpd.libs/.libs
Released wheels should rely on packaged library directories only. Cargo-target
discovery is intentionally development-only and is activated through
OPENPKPD_NATIVE_DEV=1 by the just recipe above.
At the moment, native-cvodes is development-validated but not yet considered
PyPI-wheel ready. The remaining work is wheel packaging for bundled SUNDIALS
libraries across Linux, macOS, and Windows. Until that is finished, release
validation should treat build-core-native-cvodes plus smoke-native-cvodes
as a pre-publish smoke path rather than a publishable wheel guarantee.
For wheel-oriented work, the current first target is Linux:
just build-wheel-native-cvodes
just smoke-installed-native-cvodes-wheel
On Linux, maturin needs patchelf available to repair bundled shared-library
references for the wheel. The repository CI should provide that for native
wheel jobs; local contributor machines may need to install it explicitly.
Running tests
# All tests
uv run pytest -q
# Unit tests only (fast)
uv run pytest tests/unit/ -q
# Integration tests
uv run pytest tests/integration/ -v
# With coverage report
uv run pytest --cov=openpkpd --cov-report=html
For the symbolic analytical-kernel route, the intended local/CI workflow is:
uv sync --extra dev --extra symbolic
just prewarm-symbolic-caches
uv run pytest tests/unit/model/test_symbolic_eta.py tests/unit/estimation/test_bayes.py -q
Test categories:
Marker |
Description |
|---|---|
|
Fast isolated component tests (<1 s each) |
|
End-to-end pipeline tests |
|
Comparison vs golden NONMEM output |
|
Tests taking >30 seconds |
Code style
OpenPKPD uses ruff for linting and formatting:
uv run ruff check src/ tests/
uv run ruff format src/ tests/
Type annotations are checked with mypy:
uv run mypy src/
Pre-commit hooks run both automatically on git commit:
just install-hooks
Building documentation
just build-docs-html
# or: just build-docs-and-open
Building standalone installers
To package OpenPKPD as a self-contained desktop application (no Python required on the end-user machine), see the installer build guide.
Performance-oriented development
For contributors working on runtime improvements, see the developer performance guide.
It summarizes the repository’s preferred optimization style, existing profiling entry points, validation expectations, and current high-value hotspots.
Project structure
See the User Guide for an overview of major modules. Key files:
File |
Role |
|---|---|
|
Fluent Python API |
|
NM-TRAN parser |
|
|
|
ADVAN1–4 closed-form solutions |
|
FO, FOCE, SAEM, IMP implementations |
|
Diagnostic plot functions |
Submitting a pull request
Fork the repository and create a feature branch.
Write tests for any new functionality.
Ensure all tests pass and ruff/mypy report no errors.
Open a pull request with a clear description of the change.
Licence
OpenPKPD is released under the GNU Affero General Public Licence v3 (AGPLv3).