Skip to main content

Parallel and sequential task-tree runner with matrix expansion and effects plugins.

Project description

camas-sketch-by-jph

Camas

A task runner with parallel execution, matrix expansion, MCP, and pluggable output effects.

  • For developers: live tree view that updates in place as tasks stream
  • For CI/CD: one definition drives both local runs and CI
  • For LLMs: a closed edit→validate→run loop over structured MCP

 

demo

Example

from camas import Parallel, Sequential

ci = Sequential(
  Parallel(
    "ruff format . --check",
    "npx prettier ."
  ),
  Parallel(
    "ruff check .",
    "mypy .",
    "npx eslint src/",
    "pytest",
    "npx tsc --noEmit"
  ),
)

The animated tree above is from a live test fixture — see the walkthrough.

Install

[!TIP] Add extras with PEP 621, e.g. camas[github_checks]

pipx:

pipx install camas

uv:

uv tool install camas

Nix:

nix run github:JPHutchins/camas                     # default
nix run github:JPHutchins/camas#with-github-checks  # adds httpx for the GitHubChecks effect
nix run github:JPHutchins/camas#with-check          # adds ty for `camas --check`
nix run github:JPHutchins/camas#all                 # both extras

Then scaffold a starter tasks.py in your project root:

camas --init

The starter demonstrates leaf tasks, Sequential/Parallel composition, a matrix, a Config default task, and the optional PEP 723 standalone block — cross-platform placeholder commands ready to be swapped for your real ones.

--init also creates a gitignored .camas/ directory beside tasks.py. Camas writes run logs and a per-leaf timing cache there, so camas --list can annotate tasks with an estimated duration; delete the directory to opt out. Rename or relocate it with Config(camas_dir=...).

Why camas?

camas is not a build system. camas is for the specific job of running structured trees of shell commands.

Python task runners† just Task Mage camas
Project scope Python projects only Any Any Go projects only Any
Definition language pyproject.toml TOML or @task decorator justfile DSL YAML Go Python (typed AST)
Inline anonymous parallel groups No No No (must be a named task) No Yes
Parallel execution poe yes; Invoke / taskipy no [parallel] attr deps: (parallel) mg.Deps(...) Parallel(...)
Matrix expansion No No for: + parallel:true Go loops matrix=
CLI matrix override (e.g. --PY 3.13) No No No No Yes
Live tree output No No prefixed / group modes No Termtree (default)
Pluggable output renderers No No 3 built-ins No --effects
Type checking on task definitions Partial No Editor schema Yes (Go) mypy / pyright
First release / status 2013–2020, stable 2016, stable 2017, stable 2017, stable 2026, alpha
Ecosystem Moderate (Python) Large Large Moderate None yet

poethepoet, Invoke, taskipy — pyproject.toml-bound runners that assume a Python project.

If you need... Reach for
Reproducible, hermetic builds Nix
Incremental file-based builds (skip when inputs unchanged) Task
Simple project command menu just
Parameterized tasks (--env=staging, prompts, vars) Task
Go project, build logic in Go Mage
Inline parallel/sequential trees with a live view camas
Pluggable output effects (live tree locally, summary in CI) camas
Matrix runs across versions/platforms, overridable from the CLI camas

CI integration

The renderer is swappable, not the tree. Run the same tasks.py locally with the live Termtree and in CI with Status — one flag changes the output, the pipeline definition is unchanged.

On GitHub Actions, no flag is needed. Camas detects GITHUB_ACTIONS=true and defaults --effects to (Status(output_mode="github"),) — collapsed workflow groups, ISO timestamps with millisecond precision, ANSI colors preserved.

Under an AI coding agent, no flag is needed either. Camas detects agents (the CLAUDECODE env var, or set CAMAS_AGENT=1) and defaults to the line-oriented Status renderer instead of the live Termtree, whose cursor-redraw frames bloat captured output. Prefer the camas mcp server over the CLI from an agent; a Config default_effects always overrides the detection.

- run: uv run camas check

On other CI providers (or to opt into a specific mode), spell it out:

- run: uv run camas check --effects='(Status(output_mode="errors"),)'

See the OutputMode literal and block_for doctests for the per-mode behavior. The status-modes-demo job renders one CI run per mode for visual comparison.

For per-leaf visibility in the PR Checks panel, add the GitHubChecks effect alongside Status (opt-in extra: camas[github_checks]). Each leaf task becomes its own check run, so reviewers see lint / mypy / pytest pass-or-fail individually instead of one monolithic log.

- run: |
    uv run --extra github_checks camas matrix --effects='(
      Status(output_mode="github"),
      GitHubChecks(sha="${{ github.event.pull_request.head.sha || github.sha }}"),
    )'
  env:
    GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

The job needs permissions: checks: write. Defaults read GITHUB_TOKEN, GITHUB_REPOSITORY, and GITHUB_SHA from the Actions env. The pull_request.head.sha override attaches checks to the PR head rather than the synthetic merge commit. See the github-checks-demo job for a working example.

When to use it. Two things it gives you:

  • SSOT between local dev and CI. Your camas matrix terminal view and the PR Checks panel show the same per-leaf shape (lint [PY=3.10], mypy [PY=3.14], …). The matrix definition lives once in tasks.py; CI doesn't re-encode it in YAML.
  • One runner instead of N. Camas-side parallel matrix on a single runner produces the same per-(cell, leaf) granularity that a GHA matrix gets across N runners — at 1/N the minutes and camas gives you efficient task parallelization pushing that runner to 100% utilization as much as possible. Worth it on paid-runner budgets.

The downside is that fork PRs get a read-only GITHUB_TOKEN from GitHub and can't write checks — usually a non-issue for Enterprise teams where contributors have push to the org repo.

When not to bother. OSS gets free runners — just GHA-matrix them in parallel for faster wall-clock time. The cost is small: you give up either SSOT (matrix definition moves into YAML) or per-leaf-UI granularity (one PR check entry per runner instead of per leaf) — pick one. What is a deal-breaker for OSS is fork PRs: external-contributor PRs return 403 from the Checks API, so per-leaf entries silently don't appear. The github-checks-demo job is marked continue-on-error so it doesn't block CI when that happens, but GitHubChecks isn't a workable OSS solution.

Machine-readable report (Ctrf)

For a CI artifact or input to an AI code review, add the Ctrf effect (opt-in extra: camas[ctrf]). It writes the run as a CTRF JSON report — each leaf a test with status, duration, output, command, and exit code. path= writes a file; the default is stdout.

uv run --extra ctrf camas check --effects='(Status(output_mode="errors"), Ctrf(path="ctrf-report.json"))'

Config

Bind a Config in tasks.py and bare camas (no arguments) runs its default_task:

from camas import Config, Sequential, Task

lint = Task("ruff check .")
test = Task("pytest")
ci = Sequential(lint, test, name="ci")

_ = Config(default_task=ci)

Now camas runs ci, camas --dry-run previews it, and the default's matrix axes stay overridable (camas --PY 3.13). With no Config (or no default_task), bare camas prints the full help — task listing, effects, hints — and exits non-zero.

github_task is the CI counterpart, falling back to default_task when unset; it runs under GITHUB_ACTIONS=true. Paired with the automatic Status effect, one bare camas does the right thing in both places:

_ = Config(
  default_task=ci,                            # bare `camas` locally
  github_task=Sequential(ci, "pytest --cov"), # bare `camas` under GitHub Actions
)

Config is discovered by type, so the binding's name never matters — _ by convention. Defining two is an error.

Because github_task reproduces CI, running it before a push catches a CI failure locally. If it is a named task, a one-line git hook guards every push:

echo 'exec camas check' > .git/hooks/pre-push && chmod +x .git/hooks/pre-push

git push --no-verify still bypasses it deliberately. An LLM agent needs no hook — camas_list reports the CI task as github_default, so it runs camas_run with that name before pushing.

Time budget (--under)

Once camas has timed a task's leaves (the .camas/ cache, surfaced by camas --list), camas --under=<duration> runs only the leaves whose estimate fits a wall-clock budget — the fast inner-loop subset, picked for you instead of by hand.

camas --under=1s            # budget the Config default task
camas --under=500ms check   # budget a named task or expression

It runs the mutating leaves first, in sequence, then the read-only rest in parallel — so formatters never race a checker over the same files. Mark a leaf that writes the workspace with mutates=True:

fix = Task("ruff check --fix .", mutates=True)
fmt = Task("ruff format .", mutates=True)
lint = Task("ruff check .")
$ camas --under=1s --dry-run
Time budget 1.00s — running 6 leaf(s) (0 unmeasured), excluded 2 over budget.
  over budget: pyright ~4.57s, coverage ~20.98s
fix → fmt → (mypy | ty | zuban | pyrefly)

Durations are 1s, 500ms, 2m, 1h, or a bare number of seconds. Only leaves measured to exceed the budget are excluded; a leaf with no recorded timing yet runs anyway (and is thereby measured) — skipping it would keep it forever untimed. The budget is per-leaf: a measured leaf runs when its own estimate fits, so the parallel group's wall-clock stays near the budget.

For agents, camas_run exposes the same budget as its under argument (omit task to budget the project default), and the response's budget field reports what was selected and excluded — a tight, time-boxed validate loop over structured MCP.

Path scoping (--paths)

camas <task> --paths <path>… scopes a run to changed paths instead of the whole tree. A command opts in by writing the {paths} placeholder and declaring its scope with paths= — a directory prefix, or a (changed) -> paths callable. A Sequential/Parallel may carry paths= too: it's the default scope for descendant {paths} commands that set none (the same way env/cwd propagate into a group's leaves):

py = Task("ruff format {paths}", mutates=True, paths="src")
web = Task("prettier --write {paths}", mutates=True, paths="web")
# the group's paths="." is the default for both children (neither sets its own):
autofix = Parallel(Task("ruff format {paths}"), Task("ruff check --fix {paths}"), paths=".")
_ = Config(agent=Claude(fix=Sequential(py, web, autofix)))

--paths works on any task — camas check --paths src/a.py. Without it, every {paths} resolves to its full-run default (ruff format src); with it, each {paths} command runs only over the changed files it covers, and one covering none is dropped. A command without {paths} can't be narrowed, so its paths= is a no-op and it always runs — camas errs on correctness (a tool it can't narrow might be affected by the edit). --paths is repeatable, or comma-separated.

For the Claude Code plugin, you register the auto-fix node — whatever you named it — to Config.agent.fix; the PostToolBatch hook runs that node over the just-changed files, zero model tokens. Run camas mcp init --claude to write the full Claude Code setup in one command (.mcp.json + PostToolBatch autofix hook + camas-fixer subagent + gate skill), resolving the launcher for your project and pinning to the camas version declared in tasks.py's PEP 723 block. For a bare .mcp.json for any MCP client, camas mcp init alone. Or wire it by hand:

// .claude/settings.json
{ "hooks": { "PostToolBatch": [
  { "hooks": [{ "type": "command", "command": "camas mcp fix" }] } ] } }

camas mcp fix runs the registered Config.agent.fix node (not a task named fix — that's just camas fix, your own task); it reads the changed files from the PostToolBatch event on stdin (--paths still works for a manual run). With no fix registered it is a clean no-op, so the hook is harmless without it. The launcher runs in your project's environment — camas mcp init --claude resolves and pins it; to have the camas version track tasks.py's PEP 723 block (dependencies = ["camas>=X.Y"]), re-run camas mcp init --claude after bumping.

Effects plugins

Define an Effect in your tasks.py and it's discovered automatically — usable by name from --effects and listed under camas --effects. See examples/effect-plugin/ for a typed Tail effect that streams per-task output as it arrives.

Versioning

The public API is published through versioned namespacescamas.v0 today, camas.v1 and beyond later. Import from a generation to pin the API shape: a name a generation exports is never removed or changed within that generation. The scheme tracks semver — v0 pairs with camas 0.x and is as loose as semver says 0.x is (the surface prefers to grow; breaking changes stay possible until 1.0, made deliberately and noted in releases). At 1.0 a generation freezes: a breaking change forces the next camas.vN, and published generations keep shipping, so a tasks.py or effect plugin pinned to one keeps working across upgrades.

The top-level camas namespace is the unversioned alias for the latest generation: from camas import Task, Sequential, Parallel, Effect, Config re-exports that generation's five headline definers and is kept 1:1 with its package surface. The rest of the public API for a generation — TaskNode, the TaskEvent stream, LeafState, Completion — lives in that generation's submodules, e.g. from camas.v0.task_event import TaskEvent. Everything under camas.core / camas.main is internal — it consumes whatever generations are installed and carries no stability promise.

To pin a minimum camas feature level, use your dependency declaration (camas>=0.x in pyproject.toml, or PEP 723 inline metadata) — the import path covers API shape; the package pin covers feature availability.

Standalone tasks.py (PEP 723)

For a non-Python project that wants a single-file task runner — no pyproject.toml, no venv to manage — give tasks.py a PEP 723 header and a run_cli(globals()) entry point, then run it with any PEP 723-aware tool:

# /// script
# requires-python = ">=3.11"
# dependencies = ["camas>=0.1.8"]
# ///
"""Build tasks for my project."""

from camas import Parallel, Task, run_cli

lint = Task("ruff check .")
test = Task("pytest")
check = Parallel(lint, test)

if __name__ == "__main__":
    run_cli(globals())
uv run tasks.py check     # uv reads the header, builds an ephemeral env, runs
uv run tasks.py --list    # every camas flag still works
pipx run tasks.py test

run_cli(globals()) introspects the module for Task / Sequential / Parallel and Effect bindings — exactly what camas does when it auto-discovers a tasks.py — so the standalone file behaves identically to a discovered one: camas <task> --help, --dry-run, matrix overrides, and --check all work and cite the file. run_cli is part of the stable surface (from camas import run_cli, or from camas.v0 import run_cli to pin the generation); it's imported lazily, so a plain from camas import Task doesn't pull it in.

The header owns version pinning (dependencies = ["camas>=0.1.8"]) and the interpreter floor (requires-python); it's inert to camas --check and to auto-discovery, which read the module the same way with or without it.

Reference

  • examples/ — full project layouts under test coverage. The canonical reference for how to structure tasks.py, use [tool.camas.tasks] in pyproject.toml, drive a matrix from .python-version, or scope a 2-axis matrix from the CLI.
  • src/camas/ — typed Python with thorough docstrings. camas --help and camas <task> --help link back here.
  • camas with no args runs the Config default task (or prints the full help when none is defined); camas <task> --help shows the expanded tree, matrix axes, and override flags.

Walkthrough

The animated tree at the top is generated from this tasks.py:

examples/tauri-app/tasks.py — Rust + TypeScript + Python in one tree
from pathlib import Path

from camas import Config, Parallel, Sequential, Task

src_tauri = Path("src-tauri")
python_sdk = Path("python-sdk")
node = Path("node_modules/.bin")

frontend = Sequential(
    f"{node}/prettier --write .",
    Parallel(
        f"{node}/eslint src/",
        f"{node}/tsc --noEmit",
        f"{node}/vitest run",
    ),
)

backend = Sequential(
    Task("cargo fmt --all", cwd=src_tauri),
    Parallel(
        Task("cargo clippy --all-targets --locked -- -D warnings", cwd=src_tauri),
        Task("cargo test --all-targets --locked", cwd=src_tauri),
    ),
)

sdk = Sequential(
    Task("uv run ruff check --fix .", cwd=python_sdk),
    Task("uv run ruff format .", cwd=python_sdk),
    Parallel(
        Task("uv run mypy .", cwd=python_sdk),
        Task("uv run pytest", cwd=python_sdk),
    ),
)

all = Parallel(frontend, backend, sdk)

fix = Parallel(
    f"{node}/prettier --write .",
    Task("cargo fmt --all", cwd=src_tauri),
    Sequential(
        Task("uv run ruff check --fix .", cwd=python_sdk),
        Task("uv run ruff format .", cwd=python_sdk),
    ),
)

build = Parallel(
    Task("npm run tauri build {FLAG}"),
    matrix={"FLAG": ("-- --debug", "")},
    help="Debug and release builds (FLAG='-- --debug' debug, FLAG='' release)",
)

_ = Config(default_task=all)
$ cd examples/tauri-app

List the tasks

$ camas --list
output
Available tasks from .../tauri-app/tasks.py:
  all       frontend | backend | sdk
  backend   cargo fmt --all, cargo clippy --all-targets --locked -- -D warnings | cargo test --all-targets --locked
  build     Debug and release builds (FLAG='-- --debug' debug, FLAG='' release)  [matrix: FLAG×2 (-- --debug..)]
  fix       node_modules/.bin/prettier --write . | cargo fmt --all | (uv run ruff check --fix ., uv run ruff format .)
  frontend  node_modules/.bin/prettier --write ., node_modules/.bin/eslint src/ | node_modules/.bin/tsc --noEmit | node_modules/.bin/vitest run
  sdk       uv run ruff check --fix ., uv run ruff format ., uv run mypy . | uv run pytest

Preview what all would run

$ camas --dry-run all
output
all ∥
┃ frontend →
┃ ├─ node_modules/.bin/prettier --write .
┃ └─ node_modules/.bin/eslint src/ | node_modules/.bin/tsc --noEmit | node_modules/.bin/vitest run
┃   ┃ node_modules/.bin/eslint src/
┃   ┃ node_modules/.bin/tsc --noEmit
┃   ┃ node_modules/.bin/vitest run
┃ backend →
┃ ├─ cargo fmt --all  (cwd: src-tauri)
┃ └─ cargo clippy --all-targets --locked -- -D warnings | cargo test --all-targets --locked
┃   ┃ cargo clippy --all-targets --locked -- -D warnings  (cwd: src-tauri)
┃   ┃ cargo test --all-targets --locked  (cwd: src-tauri)
┃ sdk →
┃ ├─ uv run ruff check --fix .  (cwd: python-sdk)
┃ ├─ uv run ruff format .  (cwd: python-sdk)
┃ └─ uv run mypy . | uv run pytest
┃   ┃ uv run mypy .  (cwd: python-sdk)
┃   ┃ uv run pytest  (cwd: python-sdk)

Tree-symbol key: ends a Parallel header, ends a Sequential. Children hang off (parallel siblings, run concurrently) or ├─ / └─ (sequential steps, short-circuit on first failure).

Discover a task's matrix axes and override flags

$ camas build --help
output
usage: camas build [-h] [--dry-run] [--effects EFFECTS] [--FLAG VAL[,VAL...]]

Debug and release builds (FLAG='-- --debug' debug, FLAG='' release)

runs the 'build' task:
build ∥
┃ npm run tauri build -- --debug [FLAG=-- --debug]: npm run tauri build -- --debug  FLAG=-- --debug
┃ npm run tauri build  [FLAG=]: npm run tauri build   FLAG=

Matrix axes (override with --AXIS VAL[,VAL...]):
  --FLAG  -- --debug,

Pin the matrix from the CLI

$ camas build --dry-run --FLAG '-- --debug'
output
build ∥
┃ npm run tauri build -- --debug [FLAG=-- --debug]: npm run tauri build -- --debug  FLAG=-- --debug

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

camas-0.1.21.tar.gz (132.4 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

camas-0.1.21-cp314-cp314-win_amd64.whl (534.0 kB view details)

Uploaded CPython 3.14Windows x86-64

camas-0.1.21-cp314-cp314-musllinux_1_2_x86_64.whl (970.3 kB view details)

Uploaded CPython 3.14musllinux: musl 1.2+ x86-64

camas-0.1.21-cp314-cp314-musllinux_1_2_aarch64.whl (956.8 kB view details)

Uploaded CPython 3.14musllinux: musl 1.2+ ARM64

camas-0.1.21-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (975.6 kB view details)

Uploaded CPython 3.14manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

camas-0.1.21-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl (943.4 kB view details)

Uploaded CPython 3.14manylinux: glibc 2.17+ ARM64manylinux: glibc 2.28+ ARM64

camas-0.1.21-cp314-cp314-macosx_11_0_arm64.whl (644.8 kB view details)

Uploaded CPython 3.14macOS 11.0+ ARM64

camas-0.1.21-cp313-cp313-win_amd64.whl (526.1 kB view details)

Uploaded CPython 3.13Windows x86-64

camas-0.1.21-cp313-cp313-musllinux_1_2_x86_64.whl (964.8 kB view details)

Uploaded CPython 3.13musllinux: musl 1.2+ x86-64

camas-0.1.21-cp313-cp313-musllinux_1_2_aarch64.whl (946.7 kB view details)

Uploaded CPython 3.13musllinux: musl 1.2+ ARM64

camas-0.1.21-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (970.0 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

camas-0.1.21-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl (933.8 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ ARM64manylinux: glibc 2.28+ ARM64

camas-0.1.21-cp313-cp313-macosx_11_0_arm64.whl (650.4 kB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

camas-0.1.21-cp312-cp312-win_amd64.whl (526.3 kB view details)

Uploaded CPython 3.12Windows x86-64

camas-0.1.21-cp312-cp312-musllinux_1_2_x86_64.whl (970.5 kB view details)

Uploaded CPython 3.12musllinux: musl 1.2+ x86-64

camas-0.1.21-cp312-cp312-musllinux_1_2_aarch64.whl (953.8 kB view details)

Uploaded CPython 3.12musllinux: musl 1.2+ ARM64

camas-0.1.21-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (976.3 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

camas-0.1.21-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl (940.6 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ ARM64manylinux: glibc 2.28+ ARM64

camas-0.1.21-cp312-cp312-macosx_11_0_arm64.whl (651.9 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

camas-0.1.21-cp311-cp311-win_amd64.whl (523.8 kB view details)

Uploaded CPython 3.11Windows x86-64

camas-0.1.21-cp311-cp311-musllinux_1_2_x86_64.whl (923.6 kB view details)

Uploaded CPython 3.11musllinux: musl 1.2+ x86-64

camas-0.1.21-cp311-cp311-musllinux_1_2_aarch64.whl (914.4 kB view details)

Uploaded CPython 3.11musllinux: musl 1.2+ ARM64

camas-0.1.21-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (931.6 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64manylinux: glibc 2.28+ x86-64

camas-0.1.21-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl (901.1 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ ARM64manylinux: glibc 2.28+ ARM64

camas-0.1.21-cp311-cp311-macosx_11_0_arm64.whl (641.8 kB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

File details

Details for the file camas-0.1.21.tar.gz.

File metadata

  • Download URL: camas-0.1.21.tar.gz
  • Upload date:
  • Size: 132.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for camas-0.1.21.tar.gz
Algorithm Hash digest
SHA256 6a524ac2ba1969ea9e208d9257e9956a7be9c6829897b34ad0362b7055fbc1a1
MD5 4e20cbf8c17c0a8c75ae4947dd0728d5
BLAKE2b-256 201472c124fe34bbb4d4a917121d104c77e4fee10e05ee138edc20e72fef7c6a

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.21.tar.gz:

Publisher: ci.yaml on JPHutchins/camas

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file camas-0.1.21-cp314-cp314-win_amd64.whl.

File metadata

  • Download URL: camas-0.1.21-cp314-cp314-win_amd64.whl
  • Upload date:
  • Size: 534.0 kB
  • Tags: CPython 3.14, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for camas-0.1.21-cp314-cp314-win_amd64.whl
Algorithm Hash digest
SHA256 41bf985f2aa2f7069aac98ca824bfe6801f91ee311add22ebfa66d0de346ee77
MD5 49648b364eda91b0e871ccb1f4c5bfe7
BLAKE2b-256 27fd4705ee40623cd2dd0db732291df082fa1f6dcd9de8c60d15375cbafc1d91

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.21-cp314-cp314-win_amd64.whl:

Publisher: ci.yaml on JPHutchins/camas

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file camas-0.1.21-cp314-cp314-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for camas-0.1.21-cp314-cp314-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 f5a10690dfc695c87524a231073c6bac1213f05d63eef52c12965114d5497103
MD5 2e92e27dbe993ccd52aa8b1896358a8e
BLAKE2b-256 147f8c03da74afc984c76c65f69ecb0f8aeb3385789f2348751e653d08dedf61

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.21-cp314-cp314-musllinux_1_2_x86_64.whl:

Publisher: ci.yaml on JPHutchins/camas

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file camas-0.1.21-cp314-cp314-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for camas-0.1.21-cp314-cp314-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 fc0fbb7ad5f15bc96c9da4890435e8194ec94488b93f2caaee212fe8c9128eb2
MD5 5d3ab6623e25e5f2b84f93b6d43f07bf
BLAKE2b-256 b7f770c191d5c0c1a71e123998283e0814b052bf88b8f0a64dd8c40123feb204

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.21-cp314-cp314-musllinux_1_2_aarch64.whl:

Publisher: ci.yaml on JPHutchins/camas

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file camas-0.1.21-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for camas-0.1.21-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 23c97caba1fd81d010017118f7c26afa3ff723eb1c1be7d40dd7f64c6d32923a
MD5 314e443dfcdc4c2af4e85f2b3c67a16d
BLAKE2b-256 4b3227eeae04cc6d64f053ce816c09c96b6be704a2310fb12c929a7d8d59d8f0

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.21-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl:

Publisher: ci.yaml on JPHutchins/camas

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file camas-0.1.21-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for camas-0.1.21-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 89d37e4eac4a3b8a2b555be0fdaa7a2bfbe223824b6834aed48b3580dfbbdad5
MD5 14dec66808e7a89e82d884e933098ff3
BLAKE2b-256 245ef4d476ca26e9880446c093b22ecab4366e2d3a20f8fbf734a4b8ce4ab3b9

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.21-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl:

Publisher: ci.yaml on JPHutchins/camas

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file camas-0.1.21-cp314-cp314-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for camas-0.1.21-cp314-cp314-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 9292feee7c35bcb94ff42b8dd1171c7b8fcc582431691c095bd391ee0ebea02e
MD5 e80e190deb69691d47e9ac17c5280dd3
BLAKE2b-256 c2ab7e663c50603a3709f7575e38fe162e94ca94f4fc8d21288c4f729942bfa1

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.21-cp314-cp314-macosx_11_0_arm64.whl:

Publisher: ci.yaml on JPHutchins/camas

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file camas-0.1.21-cp313-cp313-win_amd64.whl.

File metadata

  • Download URL: camas-0.1.21-cp313-cp313-win_amd64.whl
  • Upload date:
  • Size: 526.1 kB
  • Tags: CPython 3.13, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for camas-0.1.21-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 eee1b72294b4ba3813b813902453b0146d93e256cf35256c0c43e08f715eff8e
MD5 19c21e5a4c3b84e248516290052935c4
BLAKE2b-256 188367920e875e9b907514b58b712b1196fa057afe74f9b8dd8c7309c0a5c5e5

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.21-cp313-cp313-win_amd64.whl:

Publisher: ci.yaml on JPHutchins/camas

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file camas-0.1.21-cp313-cp313-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for camas-0.1.21-cp313-cp313-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 934348d492c492baa9670a0e837b155c189004de1b01cd17f1fa3c1c0ee31b7a
MD5 e07eaaeb5cd6b3f049e7e7aa2ff69416
BLAKE2b-256 faa1754e2564e05d04e4c84ab06ed2a2e252a06d32cc9dc0266ca424b064b156

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.21-cp313-cp313-musllinux_1_2_x86_64.whl:

Publisher: ci.yaml on JPHutchins/camas

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file camas-0.1.21-cp313-cp313-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for camas-0.1.21-cp313-cp313-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 0cf2f269beaa980efa11ab423aa920bb1ba4f24836a8d5727bc266c588f60a54
MD5 bf96ae0eda2ad1d5116154b33c22992d
BLAKE2b-256 321606ca0ca9e4e4f5b746a8ea1b44ce2dddcfb34199400b747e11c3ebe76ba3

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.21-cp313-cp313-musllinux_1_2_aarch64.whl:

Publisher: ci.yaml on JPHutchins/camas

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file camas-0.1.21-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for camas-0.1.21-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 e9966ecfd67b76ea6ea688c6a07bea709aba1b00046f840390539eb61c057ba5
MD5 6cdeb26af899a007671cf86d9b4a92d2
BLAKE2b-256 03cafdd4543f943bc72bce5fe4fa044f91ef97ef38d87945c36ba30a3739efb6

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.21-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl:

Publisher: ci.yaml on JPHutchins/camas

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file camas-0.1.21-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for camas-0.1.21-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 813383c3333f8ff38baf37c343699991f53a7254bf7a10cfae2f35ba8fe80b52
MD5 250f748c0c506eb45d0e31ee1ec40825
BLAKE2b-256 19da1d810bffe007908160c2435e2f51f393adbd95772658ec1ddd927c2c2390

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.21-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl:

Publisher: ci.yaml on JPHutchins/camas

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file camas-0.1.21-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for camas-0.1.21-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 4739d8839ff3ffd554ee0f8ce20cb5b157da18cdd9589107aed7b60369d051e7
MD5 2b01a5f6292e9e9353300fe9f8f6790c
BLAKE2b-256 8c9a99eabcec53a5346492e17e1701f5c0d01bee173fd9890503838eb61171d3

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.21-cp313-cp313-macosx_11_0_arm64.whl:

Publisher: ci.yaml on JPHutchins/camas

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file camas-0.1.21-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: camas-0.1.21-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 526.3 kB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for camas-0.1.21-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 2f610e400c620dd3b13d60c7aa5790cd9d8f2e29f1206e12d8ca175768925dfb
MD5 aa8a8fd92ef87051d3a26f5b544b2e30
BLAKE2b-256 6a2d13bd4e034aff58566993f43782d1fe8dec914d31e9d9000b7d9e68e8709c

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.21-cp312-cp312-win_amd64.whl:

Publisher: ci.yaml on JPHutchins/camas

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file camas-0.1.21-cp312-cp312-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for camas-0.1.21-cp312-cp312-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 f3b9fd955a0ab1fb0511ca57103b79a8247db5f4423c8f16c967e27831bbf6a5
MD5 7e842bc4ef683e9119a85775b9247691
BLAKE2b-256 ba3a5befa844a761b7976f3aedfb110d72bdc7f57c1f395864aef8cc10a9d9d3

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.21-cp312-cp312-musllinux_1_2_x86_64.whl:

Publisher: ci.yaml on JPHutchins/camas

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file camas-0.1.21-cp312-cp312-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for camas-0.1.21-cp312-cp312-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 90306cef414c752187902c79f35e0577f836834af2fceeb85ecf5e8001d672dc
MD5 c8f3b70b195a0872ad439284960499af
BLAKE2b-256 baa4a283c564bffd8c359261b75bafa0c14456fdf5af2ccf29cdb676207eeb3a

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.21-cp312-cp312-musllinux_1_2_aarch64.whl:

Publisher: ci.yaml on JPHutchins/camas

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file camas-0.1.21-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for camas-0.1.21-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 f58eb4059debd394718793effdd3d9073427f215a3c3dc6644a25f8dcea567dc
MD5 9a93a3ddc8dbc099afbf15ace670a530
BLAKE2b-256 42c5d8edc5f3b564f1d31e688da80306914552d2ae451d654b5f11ec08e44f3c

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.21-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl:

Publisher: ci.yaml on JPHutchins/camas

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file camas-0.1.21-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for camas-0.1.21-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 bf78b2f4833f338b5dc501bee0878b8582c43ea1b8477fd2e768709718659422
MD5 abfb3676fbe8cda581f44b166306e414
BLAKE2b-256 67f20e14beb22ae3ede0895b3c59efd071a0c7238486a7df076d4bfed29e43c2

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.21-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl:

Publisher: ci.yaml on JPHutchins/camas

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file camas-0.1.21-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for camas-0.1.21-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 db7ab57e80a1563646588baa489485975819d24d9e6c44cd33ff350b060b53ea
MD5 15fab465ddb22c2b736d4d39941fef47
BLAKE2b-256 2054b9be7b30cbbdedd7817d9c4adae0b0b496b261618b2532b6c01a7076cda5

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.21-cp312-cp312-macosx_11_0_arm64.whl:

Publisher: ci.yaml on JPHutchins/camas

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file camas-0.1.21-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: camas-0.1.21-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 523.8 kB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for camas-0.1.21-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 ea0a7206761dca5bfb1e06818816b04dc00a225e24a37e72537770be66f66c1b
MD5 53711b17762d8041703a62007448c6af
BLAKE2b-256 e60400196e19f0f5749a71499c14a774834f24a0edef71be7de2336d20b5035f

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.21-cp311-cp311-win_amd64.whl:

Publisher: ci.yaml on JPHutchins/camas

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file camas-0.1.21-cp311-cp311-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for camas-0.1.21-cp311-cp311-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 4db5029244e9be929880972d51a6d95d0122e774b637e8cf1ad5288ebc85786a
MD5 3e1688154761d5b0ba2903c6c049f157
BLAKE2b-256 c5ce4c7783e4925a94f70cb5315890df445dfe8a746c70b26a1ecbe939e58f25

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.21-cp311-cp311-musllinux_1_2_x86_64.whl:

Publisher: ci.yaml on JPHutchins/camas

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file camas-0.1.21-cp311-cp311-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for camas-0.1.21-cp311-cp311-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 57af6b4c766e05b0d9087e75078f7fff2022bcfc15004fb3a1851356c9d12fad
MD5 bbbf67e32d83ca31f44d00b0356409d5
BLAKE2b-256 6329f809b9b9a1d58e8068be3541af64aba502a38e5cd940e6cbce82b11383da

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.21-cp311-cp311-musllinux_1_2_aarch64.whl:

Publisher: ci.yaml on JPHutchins/camas

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file camas-0.1.21-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for camas-0.1.21-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 be7ea8d15f2e6110ad9e22d44460463e103ff2e4b9bb12ec533031598d6894cb
MD5 3fd21eaa066a15e27ee425c4e76575ae
BLAKE2b-256 959cd10aa7dd15c7df7362cb8eae2050227c5a98e0cb2e891e2e7b9c93fad53b

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.21-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl:

Publisher: ci.yaml on JPHutchins/camas

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file camas-0.1.21-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for camas-0.1.21-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 f6d40fdc89fd4b7b74b1138d78e7cc1fc54dc4ea1e49e851f84c11145489ddf3
MD5 817093e25252c6997925581d5b5edb2e
BLAKE2b-256 83038e84050b4e335df332e202d5f6209b7a893590078a9778a5e4774629c464

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.21-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl:

Publisher: ci.yaml on JPHutchins/camas

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file camas-0.1.21-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for camas-0.1.21-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 75b3e5282b50cdf53ef43184cbb9399ced996ad38286b07f2883a3b1834d7b86
MD5 8c596ccbcf4ac4e108cbdb1096218f96
BLAKE2b-256 86a44861e4e488c9e583def304d72666e419495550a8ee214972d89f8449c9d2

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.21-cp311-cp311-macosx_11_0_arm64.whl:

Publisher: ci.yaml on JPHutchins/camas

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page