A collection of reusable configuration templates for modern Python projects. Save time and maintain consistency across your projects with these pre-configured templates.
In the original Greek, spelt αΏ₯Ξ―ΞΆΞ±, pronounced ree-ZAH, and having the literal meaning root.
- π 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
Start by cloning the repository:
# Clone the repository
git clone https://github.com/jebel-quant/rhiza.git
cd rhizaThe 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 installThis will:
- Install
uvanduvxinto thebin/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.
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-readmeto update this section, or the pre-commit hook will update it automatically when you commit changes to the Makefile.
This project supports Marimo notebooks. You can run the Marimo server using:
make marimoTo ensure Marimo can import the local package (src/config), the following configuration is added to pyproject.toml:
[tool.marimo.runtime]
pythonpath = ["src"]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.
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
You can customize the look and feel of your documentation by providing your own templates.
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:
- Create the directory:
mkdir -p book/pdoc-templates - Add your Jinja2 templates (e.g.,
module.html.jinja2) to this directory.
See the pdoc documentation for more details on templating.
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:
- Create the directory:
mkdir -p book/minibook-templates - Create your custom template at
book/minibook-templates/custom.html.jinja2.
This repository provides a curated set of reusable configuration templates, organised by purpose.
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
pytesttesting 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
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
Dockerfileand.dockerignore
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)
- See GITLAB_CI.md for GitLab CI/CD setup and usage
The GitHub Actions workflows can be customized using repository variables:
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
- Default:
-
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
- Default:
To set these variables:
- Go to your repository Settings β Secrets and variables β Actions β Variables tab
- Click "New repository variable"
- Add
PYTHON_MAX_VERSIONand/orPYTHON_DEFAULT_VERSIONwith your desired values
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.
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
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 .This approach is ideal if you want to cherry-pick specific templates or customize them before integration.
First, clone the Rhiza repository to a temporary location:
# Clone to a temporary directory
cd /tmp
git clone https://github.com/jebel-quant/rhiza.gitNavigate 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/scriptsAt this stage:
- β No templates are copied yet
- β No existing files are modified
- β Only the sync mechanism is installed
β οΈ Do not merge this branch yet.
Run the sync script to apply the templates defined in '.github/template.yml'
./.rhiza/scripts/sync.shThis 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 diffIf happy with the suggested changes push them
git add .
git commit -m "Integrate Rhiza templates"
git push -u origin rhizaThis 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
If you want the sync workflow to trigger other workflows (e.g. to create pull requests), create a Personal Access Token (PAT):
- Go to GitHub Settings β Developer settings β Personal access tokens β Tokens (classic)
- Generate a new token with
repoandworkflowscopes - Add it as a repository secret named
PAT_TOKEN - Update the workflow to use
token: ${{ secrets.PAT_TOKEN }}
You can trigger the sync workflow manually:
- Go to your repository's "Actions" tab
- Select the "Sync Templates" workflow
- Click "Run workflow"
- 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.ymlconfiguration - Create a pull request with the changes (if any)
- Automatically run weekly to keep your templates up to date
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
- Test the integration - Run
make testto ensure tests pass - Run pre-commit - Execute
make fmtto verify code quality checks - Review workflows - Check GitHub Actions tabs to see workflows in action
- Customize - Adjust templates to match your project's specific needs
- Update documentation - Add project-specific instructions to your README
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 fmtto 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_VERSIONrepository variable if needed
Issue: Dev container fails to build
- Solution: Review
.devcontainer/devcontainer.jsonand ensure all dependencies are available for your project
This repository includes a template Dev Container configuration for seamless development experience in both VS Code and GitHub Codespaces.
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
- Install the "Dev Containers" extension
- Open the repository in VS Code
- Click "Reopen in Container" when prompted
- The environment will automatically set up with all dependencies
- Navigate to the repository on GitHub
- Click the green "Code" button
- Select "Codespaces" tab
- Click "Create codespace on main" (or your branch)
- 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
The repository includes workflows for building and publishing devcontainer images:
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.jsonexists
Dev containers launched locally via VS code are configured with SSH agent forwarding to enable seamless Git operations:
- Mounts your SSH directory - Your
~/.sshfolder 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
Common issues and solutions when using this configuration template.
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_rsaThis tells SSH clients on non-macOS platforms to ignore the UseKeychain directive instead of failing.
Reference: Stack Overflow solution
The project includes a hook for installing additional system dependencies and custom build steps needed across all build phases.
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 hereThe build-extras.sh script (from .rhiza/scripts/customisations) is automatically invoked during:
make install- Initial project setupmake test- Before running testsmake book- Before building documentationmake 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.
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- 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
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.
This template includes a robust release workflow that handles version bumping, tagging, and publishing.
The release process consists of two interactive steps: Bump and Release.
First, update the version in pyproject.toml:
make bumpThis command will interactively guide you through:
- Selecting a bump type (patch, minor, major) or entering a specific version
- Warning you if you're not on the default branch
- Showing the current and new version
- Prompting whether to commit the changes
- 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
Once the version is bumped and committed, run the release command:
make releaseThis command will interactively guide you through:
- Checking if your branch is up-to-date with the remote
- If your local branch is ahead, showing the unpushed commits and prompting you to push them
- Creating a git tag (e.g.,
v1.2.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
The release workflow (.github/workflows/release.yml) triggers on the tag push and:
- Validates - Checks the tag format and ensures no duplicate releases
- Builds - Builds the Python package (if
pyproject.tomlexists) - Drafts - Creates a draft GitHub release with artifacts
- PyPI - Publishes to PyPI (if not marked private)
- Devcontainer - Publishes devcontainer image (if
PUBLISH_DEVCONTAINER=true) - Finalizes - Publishes the GitHub release with links to PyPI and container images
Python Version Configuration:
- Set repository variable
PYTHON_MAX_VERSIONto 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
- Options:
- Set repository variable
PYTHON_DEFAULT_VERSIONto 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
- Options:
PyPI Publishing:
- Automatic if package is registered as a Trusted Publisher
- Use
PYPI_REPOSITORY_URLandPYPI_TOKENfor custom feeds - Mark as private with
Private :: Do Not Uploadinpyproject.toml
Devcontainer Publishing:
- Set repository variable
PUBLISH_DEVCONTAINER=trueto enable - Override registry with
DEVCONTAINER_REGISTRYvariable (defaults to ghcr.io) - Requires
.devcontainer/devcontainer.jsonto exist - Image published as
{registry}/{owner}/{repository}/devcontainer:vX.Y.Z
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
- GitHub Actions - For CI/CD capabilities
- Marimo - For interactive notebooks
- UV - For fast Python package operations