Majordome

Author

Walter Dal’Maz Silva

Published

September 7, 2026

Majordome

Getting Started

If you do not intend to build/develop the package, you can find us on Majordome on PyPI and install it with pip:

pip install majordome

To register majordome as a Jupyter kernel, run:

majordome --install-kernel

You can customize the kernel identity if needed:

majordome --install-kernel `
    --kernel-name majordome-dev `
    --display-name "Majordome (dev)"

If you don’t fit in the first group, you can build the package from source. For that, please refer to the development section below.

Tip

If you just prefer to compile locally without delving into the development environment, you can install both Rust and uv and then run uv build --wheel to generate the wheel for your platform. This will generate a wheel that you can install with uv pip install dist/*.whl or pip install dist/*.whl in the current environment. Note that this wheel will be specific to your platform and may not be compatible with other platforms, so it is recommended to use the release wheels for distribution. For more details, check the development section below.

Development

The development focuses on portability and ease of setup, so by default any dependency relying on a C/C++ compiler is forbidden. This means that the development environment can be set up on any platform without needing to install additional compilers or tools.

Majordome code is documented using Numpydoc style docstrings, and the documentation is generated by module majordome_build.documents using Quarto markdown. This design choice reflects the academic aim of the package, with reporting and notebook support as first-class citizens.

Majordome is mainly organized as a Python package with a set of Rust crates developed in separate repositories. Developing in Rust is the preferred mode as it is safer and more performant than Python, though Python is used for most day-to-day development until new functionalities reach maturity.

For the sake of compatibility with maturin and for avoiding large binaries, a single entrypoint crate is provided in the main repository at src/lib.rs, which exposes the Python API of all the other crates. Furthermore, for performance reasons and low import times, the main Python package modules are split into smaller submodules and lazy import mechanism is implemented with help of __getattr__ in __init__.py.

Project guidelines

The following project guidelines must be followed:

  • Each commit that may affect user interaction with the Python or Rust libraries must be accompanied by a short comment in the code explaining the change in the CHANGELOG.md file.

  • Tests should be added for any new functionality, bug fixes, or performance improvements. If possible, the tests should be added in the same commit as the change.

  • Before committing a modification in any of the crates, make sure that building them with uv run majordome-build works. This enforces a greedy mechanism for quality control of the code base. It is also recommended to run cargo check and cargo test manually during development at intermediate points.

Environment

The environment for developing Majordome requires at least a reasonably modern version of Python and Rust; documentation depends on Quarto and uv is used for managing the environment. The exact versions may change over time, but as of the last update, the following (minimum) versions are recommended:

Tip

Ubuntu users can bootstrap the environment with the following commands; make sure to check the latest versions of the tools and update the commands accordingly. Podman is required for building the manylinux wheel inside a container for compatibility and release in PyPI.

sudo apt-get install -y podman
sudo apt-get install -y python3-dev

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
source "$HOME/.cargo/env"

curl -LsSf https://astral.sh/uv/install.sh | sh
source "$HOME/.local/bin/env"

quarto_repo="https://github.com/quarto-dev/quarto-cli"
quarto_deb="quarto-1.9.37-linux-amd64.deb"

wget $quarto_repo/releases/download/v1.9.37/$quarto_deb
sudo apt-get install -y ./$quarto_deb

Automated release

In addition to what is described in the manual release section below, developers may also need to publish the docs, update the version, and publish the new version to GitHub and PyPI. This is fully automated by release.ps1 to ensure consistency in actions.

  • Make sure the package builds in both Windows and Linux, and that the documentation builds (many tests are included in the documentation, so this is a good sanity check for the code as well). The following commands provide a good starting point for the verifications in Windows:

    # If not yet available, install set-version:
    cargo install cargo-set-version
    
    # Check the sanity of the package:
    cargo check
    
    # Run Rust tests:
    cargo test
    
    # Run Python tests:
    uv sync --all-extras
    uv run pytest -v
    
    # Manually generate a wheel and check it:
    uv build --wheel
    uv run python -m zipfile -l dist/*.whl
  • From WSL or a Linux machine, repeat the above but also try generating the Linux wheel inside the compliant manylinux container:

    ./release.sh
  • Once verifications are done, run one of the following:

    # - You fixed something small:
    ./release.ps1 patch
    
    # - You added a new (non-breaking) feature:
    ./release.ps1 minor
    
    # - You made a breaking change:
    ./release.ps1 major
    
    # - Avoid this, unless you know exactly what you are doing:
    ./release.ps1 1.0.0

Manual release steps

The release script is useful but it can be fragile; it is better to have a fall-back plan in case something goes wrong.

  • Select the new version to release:

    $version = "major"
    $version = "minor"
    $version = "patch"
  • Update the version in both Cargo.toml and pyproject.toml:

    # If not yet available, install set-version:
    cargo install cargo-set-version
    
    # First, test with --dry-run to check the changes that will be made:
    uv version --bump $version --dry-run
    
    # After testing with the above, remove --dry-run:
    uv version --bump $version
    
    # Update cargo version to match the new version in pyproject.toml:
    cargo set-version (uv version --short)
  • You can manually check the changes in the version files; alternatively, the following snipet can be used to extract the version from Cargo.toml and use it for the commit message and GitHub release tag:

    $inSection = $false
    $version = $null
    
    foreach ($line in Get-Content "Cargo.toml") {
        if ($line -match '^\[(.+)\]\s*$') {
            $inSection = $Matches[1] -eq "package"
            continue
        }
    
        if ($inSection -and $line -match '^version\s*=\s*"([^"]+)"') {
            $version = $Matches[1]
            break
        }
    }
  • Generate the command for WSL build and inspect it before running:

    $winPath = (Get-Location).Path.Replace("\", "/")
    $wslPath = (wsl wslpath $winPath).Trim()
    $nixCmd  = "cd $wslPath && source ~/.bashrc && ./release.sh"
  • Build the wheels in both Windows and Linux (inside the compliant manylinux container):

    Remove-Item -Force -Recurse "dist/" -ErrorAction Ignore
    
    uv build --wheel
    wsl -d Ubuntu -- bash -c $nixCmd
    • Inspect the wheels (especially if new data was included):
    python -m zipfile -l dist/*.whl
  • If everything is fine, commit the changes, push to the repository:

    git add "Cargo.toml" "pyproject.toml" "Cargo.lock" "uv.lock"
    git commit -m "Release version $version"
    git tag "v$version"
    git push origin main --tags
  • Create and activate a virtual environment:

    uv venv --python python3.12 .venv
    
    # Activate on Windows:
    . .venv/Scripts/activate
    
    # Activate on Unix:
    . .venv/bin/activate
  • Install the package before generating the documentation:

    uv pip install .[docs]
  • Point Quarto to the virtual environment:

    # Windows:
    $env:QUARTO_PYTHON = ".venv/Scripts/python.exe"
    
    # Unix:
    export QUARTO_PYTHON=".venv/bin/python"
  • Generate the documentation and publish it to GitHub Pages:

    quarto render docs --to html
    quarto publish gh-pages --no-prompt --no-browser docs
  • Create the release on GitHub:

    gh release create "v$version" dist/*.whl --generate-notes
  • Publish the new version to PyPI (owners only) is done manually with uv:

    uv publish --token <copy token here>