Skip to content

Jebel-Quant/rhiza

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Rhiza Logo Rhiza

GitHub Release Synced with Rhiza

License: MIT Python versions Code style: ruff uv Hatch project CodeFactor

Gitlab Github Linux MAC OS

CI PRE-COMMIT DEPTRY MARIMO DOCKER DEVCONTAINER

Open in GitHub Codespaces

A collection of reusable configuration templates for modern Python projects. Save time and maintain consistency across your projects with these pre-configured templates.

Last Updated

In the original Greek, spelt αΏ₯Ξ―ΞΆΞ±, pronounced ree-ZAH, and having the literal meaning root.

✨ Features

  • πŸš€ CI/CD Templates - Ready-to-use GitHub Actions and GitLab CI workflows
  • πŸ§ͺ Testing Framework - Comprehensive test setup with pytest
  • πŸ“š Documentation - Automated documentation generation
  • πŸ” Code Quality - Linting, formatting, and dependency checking
  • πŸ“ Editor Configuration - Cross-platform .editorconfig for consistent coding style
  • πŸ“Š Marimo Integration - Interactive notebook support

πŸš€ Getting Started

Start by cloning the repository:

# Clone the repository
git clone https://github.com/jebel-quant/rhiza.git
cd rhiza

The project uses a Makefile as the primary entry point for all tasks. It relies on uv and uvx for fast Python package management.

Install all dependencies using:

make install

This will:

  • Install uv and uvx into the bin/ directory
  • Create a Python virtual environment in .venv/
  • Install all project dependencies from pyproject.toml

Both the .venv and bin directories are listed in .gitignore.

πŸ“‹ Available Tasks

Run make help to see all available targets:

  ____  _     _
 |  _ \| |__ (_)______ _
 | |_) | '_ \| |_  / _\`|
 |  _ <| | | | |/ / (_| |
 |_| \_\_| |_|_/___\__,_|
 
Usage:
  make <target>

Targets:

Meta

Bootstrap
  install-uv            ensure uv/uvx is installed
  install-extras        run custom build script (if exists)
  install               install
  sync                  sync with template repository as defined in .github/template.yml
  validate              validate project structure against template repository as defined in .github/template.yml
  clean                 Clean project artifacts and stale local branches

Tools
  marimo                fire up Marimo server

Quality and Formatting
  deptry                Run deptry
  fmt                   check the pre-commit hooks and the linting

Releasing and Versioning
  bump                  bump version
  release               create tag and push to remote with prompts
  post-release          perform post-release tasks

Meta
  help                  Display this help message
  customisations        list available customisation scripts
  update-readme         update README.md with current Makefile help output
  version-matrix        Emit the list of supported Python versions from pyproject.toml

Development and Testing
  test                  run all tests
  benchmark             run performance benchmarks

Documentation
  docs                  create documentation with pdoc
  marimushka            export Marimo notebooks to HTML
  book                  compile the companion book

Presentation
  presentation          generate presentation slides from PRESENTATION.md using Marp
  presentation-pdf      generate PDF presentation from PRESENTATION.md using Marp
  presentation-serve    serve presentation interactively with Marp

Customisations
  install-extras        run custom build script (if exists)
  post-release          perform post-release tasks

Agentic Workflows
  copilot               open interactive prompt for copilot
  analyse-repo          run the analyser agent to update REPOSITORY_ANALYSIS.md
  summarize-changes     summarize changes since the most recent release/tag
  install-copilot       checks for copilot and prompts to install

GitHub Helpers
  gh-install            check for gh cli existence and install extensions
  view-prs              list open pull requests
  view-issues           list open issues
  failed-workflows      list recent failing workflow runs
  whoami                check github auth status

The Makefile provides organized targets for bootstrapping, development, testing, and documentation tasks.

Note: The help output above is automatically generated from the Makefile. When you modify Makefile targets or descriptions, run make update-readme to update this section, or the pre-commit hook will update it automatically when you commit changes to the Makefile.

πŸ“Š Marimo Notebooks

This project supports Marimo notebooks. You can run the Marimo server using:

make marimo

Configuration

To ensure Marimo can import the local package (src/config), the following configuration is added to pyproject.toml:

[tool.marimo.runtime]
pythonpath = ["src"]

Dependency Management

Marimo notebooks can define their own dependencies using inline script metadata. This allows notebooks to be self-contained and reproducible.

To use the current package (rhiza) within a notebook, you can define it as a dependency and point uv to the local path. Add the following block at the top of your .py notebook file:

# /// script
# requires-python = ">=3.11"
# dependencies = [
#     "marimo",
#     "pandas",
#     "rhiza",
# ]
#
# [tool.uv.sources]
# rhiza = { path = "../.." }
# ///

Adjust the path in [tool.uv.sources] relative to the notebook's location.

Testing your documentation

Any README.md file will be scanned for Python code blocks. If any are found, they will be tested in test_readme.py.

# Some generic Python code block
import math
print("Hello, World!")
print(1 + 1)
print(round(math.pi, 2))
print(round(math.cos(math.pi/4.0), 2))

For each code block, we define a block of expected output. If the output matches the expected output, a test passes, Otherwise, it fails.

Hello, World!
2
3.14
0.71

🎨 Documentation Customization

You can customize the look and feel of your documentation by providing your own templates.

API Documentation (pdoc)

The make docs command checks for a directory at book/pdoc-templates. If found, it uses the templates within that directory to generate the API documentation.

To customize the API docs:

  1. Create the directory: mkdir -p book/pdoc-templates
  2. Add your Jinja2 templates (e.g., module.html.jinja2) to this directory.

See the pdoc documentation for more details on templating.

Companion Book (minibook)

The make book command checks for a template at book/minibook-templates/custom.html.jinja2. If found, it uses this template for the minibook generation.

To customize the book:

  1. Create the directory: mkdir -p book/minibook-templates
  2. Create your custom template at book/minibook-templates/custom.html.jinja2.

πŸ“ Available Templates

This repository provides a curated set of reusable configuration templates, organised by purpose.

🌱 Core Project Configuration

Foundational files that define project structure, standards, and contribution practices.

  • .gitignore β€” Sensible defaults for Python projects
  • .editorconfig β€” Editor configuration to enforce consistent coding standards
  • ruff.toml β€” Configuration for the Ruff linter and formatter
  • pytest.ini β€” Configuration for the pytest testing framework
  • Makefile β€” Simple make targets for common development tasks
  • CODE_OF_CONDUCT.md β€” Generic code of conduct for open-source projects
  • CONTRIBUTING.md β€” Generic contributing guidelines for open-source projects

πŸ”§ Developer Experience

Tooling that improves local development, onboarding, and reproducibility.

  • .devcontainer/ β€” Development container setup (VS Code / Dev Containers)
  • .pre-commit-config.yaml β€” Common and useful pre-commit hooks
  • docker/ β€” Example Dockerfile and .dockerignore

πŸš€ CI / CD & Automation

Templates related to continuous integration, delivery, and repository automation.

  • .github/ β€” GitHub Actions workflows, scripts, and repository templates
  • .gitlab/ β€” GitLab CI/CD workflows (equivalent to GitHub Actions)

βš™οΈ Workflow Configuration

The GitHub Actions workflows can be customized using repository variables:

Python Version Control

Control which Python versions are used in your workflows:

  • PYTHON_MAX_VERSION - Maximum Python version for CI testing matrix

    • Default: '3.14' (tests on 3.11, 3.12, 3.13, 3.14)
    • Set to '3.13' to test on 3.11, 3.12, 3.13 only
    • Set to '3.12' to test on 3.11, 3.12 only
    • Set to '3.11' to test on 3.11 only
  • PYTHON_DEFAULT_VERSION - Default Python version for release, pre-commit, book, and marimo workflows

    • Default: '3.14'
    • Set to '3.12' or '3.13' if dependencies are not compatible with newer versions

To set these variables:

  1. Go to your repository Settings β†’ Secrets and variables β†’ Actions β†’ Variables tab
  2. Click "New repository variable"
  3. Add PYTHON_MAX_VERSION and/or PYTHON_DEFAULT_VERSION with your desired values

🧩 Bringing Rhiza into an Existing Project

Rhiza provides reusable configuration templates that you can integrate into your existing Python projects. You can choose to adopt all templates or selectively pick the ones that fit your needs.

Prerequisites

Before integrating Rhiza into your existing project:

  • Python 3.11+ - Ensure your project supports Python 3.11 or newer
  • Git - Your project should be a Git repository
  • Backup - Consider committing any uncommitted changes before integration
  • Review - Review the Available Templates section to understand what could be added

Quick Start: Automated Injection

The fastest way to integrate Rhiza is using the provided inject_rhiza.sh script:

# Navigate to your repository
cd /path/to/your/project

# Run the injection script
uvx rhiza .

This will:

  • βœ… Create a default template configuration (.github/template.yml)
  • βœ… Perform an initial sync of a basic set of templates
  • βœ… Provide clear next steps for review and customization

Options:

  • --branch <branch> - Use a specific rhiza branch (default: main)
  • --help - Show detailed usage information

Example with branch option:

# Use a development branch
uvx --branch develop .

Method 1: Manual Integration (Selective Adoption)

This approach is ideal if you want to cherry-pick specific templates or customize them before integration.

Step 1: Clone Rhiza

First, clone the Rhiza repository to a temporary location:

# Clone to a temporary directory
cd /tmp
git clone https://github.com/jebel-quant/rhiza.git

Step 2: Copy Desired Templates

Navigate to your project and copy the configuration files you need:

# Navigate to your project
cd /path/to/your/project

# We recommend working on a fresh branch
git checkout -b rhiza

# Ensure required directories exist
mkdir -p .github/workflows
mkdir -p .rhiza/scripts

# Copy the template configuration
cp /tmp/rhiza/.github/template.yml .github/template.yml

# Copy the sync helper script
cp /tmp/rhiza/.rhiza/scripts/sync.sh .rhiza/scripts

At this stage:

  • ❌ No templates are copied yet
  • ❌ No existing files are modified
  • βœ… Only the sync mechanism is installed
  • ⚠️ Do not merge this branch yet.

Step 3: Perform the first sync

Run the sync script to apply the templates defined in '.github/template.yml'

./.rhiza/scripts/sync.sh

This will:

  • Fetch the selected templates from the Rhiza repository
  • Apply them locally according to your include/exclude rules
  • Stage or commit the resulting changes on the current branch

Review the changes carefully:

git status
git diff

If happy with the suggested changes push them

git add .
git commit -m "Integrate Rhiza templates"
git push -u origin rhiza

Method 2: Automated Sync (Continuous Updates)

This approach keeps your project’s configuration in sync with Rhiza’s latest templates while giving you control over which files are applied.

Prerequisites:

  • A .github/template.yml file exists, defining which templates to include or exclude.
  • The first manual sync (./.rhiza/scripts/sync.sh) has been performed.
  • The .github/workflows/sync.yml workflow is present in your repository.

The workflow can run:

On a schedule β€” e.g., weekly updates Manually β€” via the GitHub Actions β€œRun workflow” button

⚠️ .github/template.yml remains the source of truth. All automated updates are driven by its include/exclude rules.

Step 1: Configure GitHub Token

If you want the sync workflow to trigger other workflows (e.g. to create pull requests), create a Personal Access Token (PAT):

  1. Go to GitHub Settings β†’ Developer settings β†’ Personal access tokens β†’ Tokens (classic)
  2. Generate a new token with repo and workflow scopes
  3. Add it as a repository secret named PAT_TOKEN
  4. Update the workflow to use token: ${{ secrets.PAT_TOKEN }}

Step 2: Run Initial Sync (again)

You can trigger the sync workflow manually:

  1. Go to your repository's "Actions" tab
  2. Select the "Sync Templates" workflow
  3. Click "Run workflow"
  4. Review and merge the resulting pull request

The workflow will:

  • Download the latest templates from Rhiza
  • Copy them to your project based on your template.yml configuration
  • Create a pull request with the changes (if any)
  • Automatically run weekly to keep your templates up to date

What to Expect After Integration

After integrating Rhiza, your project will have:

  • Automated CI/CD - GitHub Actions workflows for testing, linting, and releases
  • Code Quality Tools - Pre-commit hooks, ruff formatting, and pytest configuration
  • Task Automation - Makefile with common development tasks (make test, make fmt, etc.)
  • Dev Container - Optional VS Code/Codespaces development environment
  • Documentation - Templates for automated documentation generation

Next Steps

  1. Test the integration - Run make test to ensure tests pass
  2. Run pre-commit - Execute make fmt to verify code quality checks
  3. Review workflows - Check GitHub Actions tabs to see workflows in action
  4. Customize - Adjust templates to match your project's specific needs
  5. Update documentation - Add project-specific instructions to your README

Troubleshooting

Issue: Makefile targets conflict with existing scripts

  • Solution: Review the Makefile and merge targets with your existing build scripts, or rename conflicting targets

Issue: Pre-commit hooks fail on existing code

  • Solution: Run make fmt to fix formatting issues, or temporarily exclude certain files in .pre-commit-config.yaml

Issue: GitHub Actions workflows fail

  • Solution: Check Python version compatibility and adjust PYTHON_MAX_VERSION repository variable if needed

Issue: Dev container fails to build

  • Solution: Review .devcontainer/devcontainer.json and ensure all dependencies are available for your project

πŸ–₯️ Dev Container Compatibility

This repository includes a template Dev Container configuration for seamless development experience in both VS Code and GitHub Codespaces.

What's Configured

The .devcontainer setup provides:

  • 🐍 Python 3.14 runtime environment
  • πŸ”§ UV Package Manager - Fast Python package installer and resolver
  • ⚑ Makefile - For running project workflows
  • πŸ§ͺ Pre-commit Hooks - Automated code quality checks
  • πŸ“Š Marimo Integration - Interactive notebook support with VS Code extension
  • πŸ” Python Development Tools - Pylance, Python extension, and optimized settings
  • πŸš€ Port Forwarding - Port 8080 for development servers
  • πŸ” SSH Agent Forwarding - Full Git functionality with your host SSH keys

Usage

In VS Code

  1. Install the "Dev Containers" extension
  2. Open the repository in VS Code
  3. Click "Reopen in Container" when prompted
  4. The environment will automatically set up with all dependencies

In GitHub Codespaces

  1. Navigate to the repository on GitHub
  2. Click the green "Code" button
  3. Select "Codespaces" tab
  4. Click "Create codespace on main" (or your branch)
  5. Your development environment will be ready in minutes

The dev container automatically runs the initialization script that:

  • Installs UV package manager
  • Configures the Python virtual environment
  • Installs project dependencies
  • Sets up pre-commit hooks

Publishing Devcontainer Images

The repository includes workflows for building and publishing devcontainer images:

CI Validation

The DEVCONTAINER workflow automatically validates that your devcontainer builds successfully:

  • Triggers on changes to .devcontainer/** files or the workflow itself
  • Builds the image without publishing (push: never)
  • Works on pushes to any branch and pull requests
  • Gracefully skips if no .devcontainer/devcontainer.json exists

VS Code Dev Container SSH Agent Forwarding

Dev containers launched locally via VS code are configured with SSH agent forwarding to enable seamless Git operations:

  • Mounts your SSH directory - Your ~/.ssh folder is mounted into the container
  • Forwards SSH agent - Your host's SSH agent is available inside the container
  • Enables Git operations - Push, pull, and clone using your existing SSH keys
  • Works transparently - No additional setup required in VS Code dev containers

Troubleshooting

Common issues and solutions when using this configuration template.


SSH authentication fails on macOS when using devcontainer

Symptom: When building or using the devcontainer on macOS, Git operations (pull, push, clone) fail with SSH authentication errors, even though your SSH keys work fine on the host.

Cause: macOS SSH config often includes UseKeychain yes, which is a macOS-specific directive. When the devcontainer mounts your ~/.ssh directory, other platforms (Linux containers) don't recognize this directive and fail to parse the SSH config.

Solution: Add IgnoreUnknown UseKeychain to the top of your ~/.ssh/config file on your Mac:

# At the top of ~/.ssh/config
IgnoreUnknown UseKeychain

Host *
  AddKeysToAgent yes
  UseKeychain yes
  IdentityFile ~/.ssh/id_rsa

This tells SSH clients on non-macOS platforms to ignore the UseKeychain directive instead of failing.

Reference: Stack Overflow solution

πŸ”§ Custom Build Extras

The project includes a hook for installing additional system dependencies and custom build steps needed across all build phases.

Using build-extras.sh

Create a file .rhiza/scripts/customisations/build-extras.sh in your repository to install system packages or dependencies (this repository uses a dedicated customisations folder for repo-specific scripts):

#!/bin/bash
set -euo pipefail

# Example: Install graphviz for diagram generation
sudo apt-get update
sudo apt-get install -y graphviz

# Add other custom installation commands here

When it Runs

The build-extras.sh script (from .rhiza/scripts/customisations) is automatically invoked during:

  • make install - Initial project setup
  • make test - Before running tests
  • make book - Before building documentation
  • make docs - Before generating API documentation

This ensures custom dependencies are available whenever needed throughout the build lifecycle. The Makefile intentionally only checks the .rhiza/scripts/customisations folder for repository-specific hooks such as build-extras.sh and post-release.sh.

Important: Exclude from Template Updates

If you customize this file, add it to the exclude list in your action.yml configuration to prevent it from being overwritten during template updates. Use the customisations path to avoid clobbering:

exclude: |
  .rhiza/scripts/customisations/build-extras.sh

Common Use Cases

  • Installing graphviz for diagram rendering
  • Adding LaTeX for mathematical notation
  • Installing system libraries for specialized tools
  • Setting up additional build dependencies
  • Downloading external resources or tools

Post-release scripts

If you need repository-specific post-release tasks, place a post-release.sh script in .rhiza/scripts/customisations/post-release.sh. The Makefile will only look in the customisations folder for that hook.

πŸš€ Releasing

This template includes a robust release workflow that handles version bumping, tagging, and publishing.

The Release Process

The release process consists of two interactive steps: Bump and Release.

1. Bump Version

First, update the version in pyproject.toml:

make bump

This command will interactively guide you through:

  1. Selecting a bump type (patch, minor, major) or entering a specific version
  2. Warning you if you're not on the default branch
  3. Showing the current and new version
  4. Prompting whether to commit the changes
  5. Prompting whether to push the changes

The script ensures safety by:

  • Checking for uncommitted changes before bumping
  • Validating that the tag doesn't already exist
  • Verifying the version format

2. Release

Once the version is bumped and committed, run the release command:

make release

This command will interactively guide you through:

  1. Checking if your branch is up-to-date with the remote
  2. If your local branch is ahead, showing the unpushed commits and prompting you to push them
  3. Creating a git tag (e.g., v1.2.4)
  4. Pushing the tag to the remote, which triggers the GitHub Actions release workflow

The script provides safety checks by:

  • Warning if you're not on the default branch
  • Verifying no uncommitted changes exist
  • Checking if the tag already exists locally or on remote
  • Showing the number of commits since the last tag

What Happens After Release

The release workflow (.github/workflows/release.yml) triggers on the tag push and:

  1. Validates - Checks the tag format and ensures no duplicate releases
  2. Builds - Builds the Python package (if pyproject.toml exists)
  3. Drafts - Creates a draft GitHub release with artifacts
  4. PyPI - Publishes to PyPI (if not marked private)
  5. Devcontainer - Publishes devcontainer image (if PUBLISH_DEVCONTAINER=true)
  6. Finalizes - Publishes the GitHub release with links to PyPI and container images

Configuration Options

Python Version Configuration:

  • Set repository variable PYTHON_MAX_VERSION to control maximum Python version in CI tests
    • Options: '3.11', '3.12', '3.13', or '3.14' (default)
    • Example: Set to '3.13' to test on Python 3.11, 3.12, and 3.13 only
  • Set repository variable PYTHON_DEFAULT_VERSION to control default Python version in workflows
    • Options: '3.11', '3.12', '3.13', or '3.14' (default)
    • Example: Set to '3.12' if dependencies are not compatible with Python 3.14
    • Used in release, pre-commit, book, and marimo workflows

PyPI Publishing:

  • Automatic if package is registered as a Trusted Publisher
  • Use PYPI_REPOSITORY_URL and PYPI_TOKEN for custom feeds
  • Mark as private with Private :: Do Not Upload in pyproject.toml

Devcontainer Publishing:

  • Set repository variable PUBLISH_DEVCONTAINER=true to enable
  • Override registry with DEVCONTAINER_REGISTRY variable (defaults to ghcr.io)
  • Requires .devcontainer/devcontainer.json to exist
  • Image published as {registry}/{owner}/{repository}/devcontainer:vX.Y.Z

🀝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ™ Acknowledgments

  • GitHub Actions - For CI/CD capabilities
  • Marimo - For interactive notebooks
  • UV - For fast Python package operations

About

A collection of reusable configuration templates for modern Python projects

Resources

License

Code of conduct

Contributing

Stars

Watchers

Forks

Contributors 8