Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Tooling Decisions

Why the project uses specific tools for environment management, orchestration, storage, quality, and documentation. Each section states the problem the tool solves, why it was chosen over alternatives, and what trade-offs come with it.


Environment management: Pixi

The project uses Pixi as its environment and task manager.

The problem. The project depends on both Python packages (from PyPI) and non-Python system binaries — PostgreSQL (for Prefect server), Graphviz (dot binary for provenance graph rendering), and Node.js (for Jupyter Book 2). A pure-pip approach cannot install these.

Why Pixi:

The trade-off: Pixi is less widely known than conda or Poetry. Contributors need to install it separately. The project mitigates this by documenting the installation step prominently in the getting-started guide.


Build system: Hatchling

The project uses Hatchling as its Python build backend.

Why Hatchling:


Orchestration dispatch: Prefect

The framework uses Prefect as its orchestration dispatch layer, not as its workflow engine. Artisan owns pipeline definition, step sequencing, caching, and provenance. Prefect handles parallel task dispatch and observability.

Why Prefect:

The trade-off: Prefect requires a server process for SLURM execution (workers need a coordination point). The project manages this via prefect-start and prefect-stop pixi tasks. For local-only execution, the server is not required.

See: How Artisan Uses Prefect for the dispatch architecture diagram.


SLURM integration: submitit and prefect-submitit

HPC cluster execution uses submitit (Meta’s SLURM job submission library) through the prefect-submitit bridge.

Why submitit:

Why prefect-submitit:


Storage: Delta Lake and Polars

The framework stores all pipeline results — artifacts, provenance edges, execution records — in Delta Lake tables, queried via Polars.

The problem. HPC clusters provide shared filesystems, not managed database services. A storage solution that requires PostgreSQL or Redis is impractical. Meanwhile, storing results as loose files creates filesystem bloat (millions of small files) and makes querying results difficult.

Why Delta Lake:

Why Polars (not pandas):

The trade-off: Delta Lake adds write overhead (transaction log management, ZSTD compression). This is negligible compared to operation execution time, but means the framework is not optimized for sub-second microbenchmarks.

See: Storage and Delta Lake for the full table architecture and staging-commit pattern.


Content hashing: xxhash

All content-addressed IDs use xxHash (specifically xxh3_128).

Why xxh3_128:

Why not SHA-256? Cryptographic security is unnecessary for content addressing. xxh3_128 is an order of magnitude faster than SHA-256 and the collision resistance is more than sufficient for this use case.


Schema validation: Pydantic

All data models — artifact schemas, execution configs, pipeline specs, operation parameters — use Pydantic for validation.

Why Pydantic:


Formatting and linting: Ruff

The project uses Ruff for formatting and linting, replacing Black, isort, flake8, and their plugin ecosystem with a single tool.

Why Ruff:

The project also enforces from __future__ import annotations in all files via Ruff’s isort integration (isort.required-imports).


Static type checking: mypy

The project uses mypy in strict mode for static type analysis.

Why mypy:


Pre-commit hooks

The project uses pre-commit to run automated checks before each commit. The hook configuration (.pre-commit-config.yaml) includes:

HookPurpose
ruff (format + lint)Code formatting and lint rules
mypyStatic type checking
prettierYAML, Markdown, and JSON formatting
blacken-docsFormat Python code blocks in documentation
codespellCatch common misspellings
shellcheckLint shell scripts
validate-pyprojectValidate pyproject.toml schema
check-jsonschemaValidate GitHub workflow and ReadTheDocs configs
sp-repo-reviewScientific Python community standards compliance
pre-commit-hooksFile hygiene (trailing whitespace, merge conflicts, large files, test naming)

Pre-commit runs in CI and locally. Install hooks with pre-commit install from the dev environment.


Testing: pytest and pytest-xdist

The project uses pytest for all tests, with pytest-xdist for parallel integration test execution.

Test organization:

Why sequential unit tests + parallel integration tests? Unit tests are fast enough that parallelization overhead is not worth the complexity. Integration tests are slow enough (seconds each) that running them in parallel provides a meaningful speedup, and they are designed to be independent (each creates its own temporary Delta Lake store).


Provenance visualization: Graphviz

Provenance graphs are rendered using Graphviz (the dot layout engine) via the graphviz Python package.

Why Graphviz:

Graphviz requires a system binary (dot), which is why it is installed via conda-forge rather than pip. The Python graphviz package provides the API; the conda-forge graphviz package provides the binary.


Documentation: Jupyter Book 2 and MyST

Documentation is built with Jupyter Book 2 using MyST Markdown.

Why Jupyter Book 2:

Jupyter Book 2 requires Node.js, which is installed via conda-forge in the docs environment.


Console output: Rich

The framework uses Rich for styled console output in logging. Log levels and URLs are colorized via regex highlighting, providing readable output without requiring a full TUI framework.


AI assistance: Claude Code plugin

The problem. Writing operations and pipelines requires knowing framework conventions, base classes, and patterns. New contributors face a steep ramp-up.

Why a plugin. The plugin is defined at the repo root using the inline marketplace pattern (.claude-plugin/marketplace.json with "source": "./"). Skills live in skills/ at the repo root and are distributed via the Claude Code marketplace — no --plugin-dir flag needed.

What’s included. Four skills in skills/:

The trade-off. Requires Claude Code. Skills need updating when framework APIs change.


See also