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.19.tar.gz (132.2 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.19-cp314-cp314-win_amd64.whl (533.5 kB view details)

Uploaded CPython 3.14Windows x86-64

camas-0.1.19-cp314-cp314-musllinux_1_2_x86_64.whl (969.3 kB view details)

Uploaded CPython 3.14musllinux: musl 1.2+ x86-64

camas-0.1.19-cp314-cp314-musllinux_1_2_aarch64.whl (955.8 kB view details)

Uploaded CPython 3.14musllinux: musl 1.2+ ARM64

camas-0.1.19-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (974.6 kB view details)

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

camas-0.1.19-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl (942.4 kB view details)

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

camas-0.1.19-cp314-cp314-macosx_11_0_arm64.whl (650.3 kB view details)

Uploaded CPython 3.14macOS 11.0+ ARM64

camas-0.1.19-cp313-cp313-win_amd64.whl (525.3 kB view details)

Uploaded CPython 3.13Windows x86-64

camas-0.1.19-cp313-cp313-musllinux_1_2_x86_64.whl (963.8 kB view details)

Uploaded CPython 3.13musllinux: musl 1.2+ x86-64

camas-0.1.19-cp313-cp313-musllinux_1_2_aarch64.whl (945.6 kB view details)

Uploaded CPython 3.13musllinux: musl 1.2+ ARM64

camas-0.1.19-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (969.0 kB view details)

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

camas-0.1.19-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl (932.7 kB view details)

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

camas-0.1.19-cp313-cp313-macosx_11_0_arm64.whl (649.3 kB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

camas-0.1.19-cp312-cp312-win_amd64.whl (525.6 kB view details)

Uploaded CPython 3.12Windows x86-64

camas-0.1.19-cp312-cp312-musllinux_1_2_x86_64.whl (969.2 kB view details)

Uploaded CPython 3.12musllinux: musl 1.2+ x86-64

camas-0.1.19-cp312-cp312-musllinux_1_2_aarch64.whl (952.8 kB view details)

Uploaded CPython 3.12musllinux: musl 1.2+ ARM64

camas-0.1.19-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (975.3 kB view details)

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

camas-0.1.19-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl (939.7 kB view details)

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

camas-0.1.19-cp312-cp312-macosx_11_0_arm64.whl (650.7 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

camas-0.1.19-cp311-cp311-win_amd64.whl (523.2 kB view details)

Uploaded CPython 3.11Windows x86-64

camas-0.1.19-cp311-cp311-musllinux_1_2_x86_64.whl (922.4 kB view details)

Uploaded CPython 3.11musllinux: musl 1.2+ x86-64

camas-0.1.19-cp311-cp311-musllinux_1_2_aarch64.whl (913.3 kB view details)

Uploaded CPython 3.11musllinux: musl 1.2+ ARM64

camas-0.1.19-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (930.5 kB view details)

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

camas-0.1.19-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl (900.2 kB view details)

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

camas-0.1.19-cp311-cp311-macosx_11_0_arm64.whl (647.8 kB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

File details

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

File metadata

  • Download URL: camas-0.1.19.tar.gz
  • Upload date:
  • Size: 132.2 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.19.tar.gz
Algorithm Hash digest
SHA256 49696ed672d2e351c2dfb312b2b51e8eb65e006a7408dae5696e407f364c691d
MD5 5df1b2ab73c0483655e577b5a248bebc
BLAKE2b-256 81335e849bd06a9ececb9e5cccd192467f830e76872bd4e5c80ebb601f5cd99f

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.19.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.19-cp314-cp314-win_amd64.whl.

File metadata

  • Download URL: camas-0.1.19-cp314-cp314-win_amd64.whl
  • Upload date:
  • Size: 533.5 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.19-cp314-cp314-win_amd64.whl
Algorithm Hash digest
SHA256 f6870935b86fdd589fa0baa31c04da3b47d1871e91378ea35c791b58d4247b42
MD5 61f8a05f247b76d98880aba674b52541
BLAKE2b-256 0c59b80fc6fbc12e7bb6ad1491a8ecb10301826a38c54e5d5793c7525d7a218a

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.19-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.19-cp314-cp314-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for camas-0.1.19-cp314-cp314-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 d932e4d49ec4ed834c051d97ee0bf8cd3e940af35674b880b1d6a98d3a359817
MD5 ea1266abf8c87fe237eaefff043985b1
BLAKE2b-256 560693245db327b172ae79b1d82a2a6c4bc4051672e758188914c04c387b4e71

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.19-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.19-cp314-cp314-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for camas-0.1.19-cp314-cp314-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 ccda5169bee30ef7f21ca32d7f0c97c747bc6eea7269caa33e1444f8a48e7ad2
MD5 c9f6e80c3752bcd796cdf8c1e7ebe266
BLAKE2b-256 1d9456896e61da414061fc73ec1b3212549a5197806d7b6b2ecf6e5fe6d556ad

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.19-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.19-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.19-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 3696c9477d7edf53368d8db5e16f6ce1232052dc430bd592a25fca488bff1441
MD5 5c1ce7c2a63ccd71881c206d7ba66297
BLAKE2b-256 e052317407189947917f68571ae9fe9b6a363e8ea9a8f7bfbc64e0e391a32695

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.19-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.19-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for camas-0.1.19-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 2f9268b7f69a225ed3010bcca124160a12722355711fb42a30355d956691d0ec
MD5 80bfbe400402b38455b671bd7022b2a8
BLAKE2b-256 cdfdd929075a785bf9a6c9984a54f37c3f14afa1d4056a79822e1818630dda33

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.19-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.19-cp314-cp314-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for camas-0.1.19-cp314-cp314-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 f8a736d6ea5e99757ce0bda6217daf0a629c4284dcb6e77ad48ef1ed6c5a4a95
MD5 60a969f1850d769397453272115e8909
BLAKE2b-256 83f07a89e192d768c956bc0cfb85fca237e0cf6980afc98922763dd95b5c6bed

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.19-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.19-cp313-cp313-win_amd64.whl.

File metadata

  • Download URL: camas-0.1.19-cp313-cp313-win_amd64.whl
  • Upload date:
  • Size: 525.3 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.19-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 096e754a587255ecaaf87259df88ae0539825aa214e20ef9a8b61288bcf64d96
MD5 bf0f018faa1c1c822b25f8aa3e19e0b6
BLAKE2b-256 14540a20f083b6a95fa8262740a366371ccc8684d3607a5bce3d9a51e07574b0

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.19-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.19-cp313-cp313-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for camas-0.1.19-cp313-cp313-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 b9827c0b49a6e2e259688b5afea021ca49df1c19f92f03e4753e3790b3b3c94d
MD5 3c9b165e2792d80d72d777f208d49060
BLAKE2b-256 472528832eefb9341609f5f9fca36e88b7e2561a044a754ec0d39db6471146a6

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.19-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.19-cp313-cp313-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for camas-0.1.19-cp313-cp313-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 4fd99c9a5d2d8c44ff5f3ec773d4a8e6d14be7956c7f91c77502520e17b74ac1
MD5 28ea4b4c339d1bf3e21f1482998d95ae
BLAKE2b-256 186924a42eab46ef546d548613caa5660979b84ffe949d60c516fc0bdc7f4591

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.19-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.19-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.19-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 dd4c88363b4f3f2ad807a3b5ce0ef292fd9f4fede86dbb152690ebf297b1e59f
MD5 31a124e03e1f78c6540a4ab0f998bb83
BLAKE2b-256 9eb7bc645cb0720db02d133782aa1987085564842309452cceedf623d91fb06e

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.19-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.19-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for camas-0.1.19-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 08657bea87a396992f302d53b9a84977fedd92e8fbb7ea05a6401dbf2f81d5b8
MD5 d4093a76aeb94048bdd9f8260a86378e
BLAKE2b-256 45e020b2b8d4b8acca32d06d1c194881c714fecc3f4d98c2310bc89c601e6266

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.19-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.19-cp313-cp313-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for camas-0.1.19-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 3d2cf9af84c5ffb0b85ae80ec2fafc0e9d92cfe81a9b71222a48d2cc4266c496
MD5 78245f1c79ebc5d1b4492d98733395dc
BLAKE2b-256 6b03592edbc511f6e8716f0e8c24be22fe9143c8651bb7b1ebfbe45a6dc5bfa4

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.19-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.19-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: camas-0.1.19-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 525.6 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.19-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 6c87a14fb2e8e9f5c645cfad225a539256bff3d39baac5bb24521bda405e4dcb
MD5 0228b2c1abee8f3b43fd4aa160306108
BLAKE2b-256 7235a97a8e3dde40794cc6809897f49fe6b55574f86726e0f7f0c790aa037182

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.19-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.19-cp312-cp312-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for camas-0.1.19-cp312-cp312-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 cea7965e0882bb0846582d05e8486251af21379e2eb4a6ecea7d0331334644a1
MD5 ba8ac385e8bab3efb5591246039afa76
BLAKE2b-256 ea4c614ef15374babfd18ccedd1b4cef9d8e7df1727639a5d0e418cb39bc242f

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.19-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.19-cp312-cp312-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for camas-0.1.19-cp312-cp312-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 0bdcc27123d0967bd10d534feb5d7c25d3c35321572354f3cac529eca754d166
MD5 efda32a00150d556b9bf7e364dcd2bdf
BLAKE2b-256 b63a79892a93139b8e99b057b8f439660c83e4bde0ffa1462323150db9cf2bb8

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.19-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.19-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.19-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 24c09fd3817914ac1cc78eb8fb97c47a7a4c8e8cbd8054717f1860ac9d512266
MD5 f4e481641bb38e743abaa2fcbb73e079
BLAKE2b-256 9f2f22132e5f3e784d735400302a8a039029af4a997788fefc2b669b8942130b

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.19-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.19-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for camas-0.1.19-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 bbf7aa9165217de750fa140d0105ad83855253f2e89c9ea15bc8e01f1dd075e9
MD5 e2bdf6c13000a46fd14f2808f5f8e5d7
BLAKE2b-256 6188ac7924359f024240ea604b086466151c31edf245f92ef39473334a632aab

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.19-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.19-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for camas-0.1.19-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 f0a69ac85a75a508de447bd9cccfb5fb7cac98bb16e79700d4b7183a87df74d2
MD5 d64ebe987663e7909fcdbc2573850cd8
BLAKE2b-256 e544a65c1b49137b61d7e3437997988cb6e1b14d9817861e8491b78566e68bac

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.19-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.19-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: camas-0.1.19-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 523.2 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.19-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 4d26cdf54389dbbc3a888a20ba7171704c99c99416cd4292aa3e6b320ff3d095
MD5 229213c827d40a7af6fb51759510d53e
BLAKE2b-256 ab4575c667923ec882bba1804a21aa347e65acd4caa74d90c1e3d51b71680ea5

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.19-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.19-cp311-cp311-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for camas-0.1.19-cp311-cp311-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 8afde176830ed0a5324152534e5180744b2cba4b660989b6a2e6cac79dc2abde
MD5 635029aa23186d26fb7443d4baebd0a7
BLAKE2b-256 bbb0e1bd33a78689ae44201f096762e113f98f8a9d41ee4aca6f2417c208609b

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.19-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.19-cp311-cp311-musllinux_1_2_aarch64.whl.

File metadata

File hashes

Hashes for camas-0.1.19-cp311-cp311-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 aa598738a8dc776be9f4051405821afac34ec720996b4939e586e5b693105871
MD5 1d5e0625a7cba41fa93033e1fddfca47
BLAKE2b-256 0386ff018017b60ef0e4a0fa3a22ece73e5bb6c5f7fbeac35f454af3b67b1ff0

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.19-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.19-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.19-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 7563fc71546eb3aaabc6b122765d676e72dda063997a342c90f30471c364db20
MD5 198855040549bfe170dd2371dda8c81b
BLAKE2b-256 b1261b8befceacfbdad8d2f7a7b900d527d28b693ea7450bcca32f5ded1420ed

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.19-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.19-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for camas-0.1.19-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 0d0911d56ce4683a4e7dbc075a4e5bef4b716499423e3c067d4171dc5962ce43
MD5 3ea77bf431b917698db73619e82a4b78
BLAKE2b-256 81d91f82a78455b1f72de36ea8e8f9653ea36c657ca6055b875b218a2548c100

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.19-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.19-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for camas-0.1.19-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 3deafbecb708fec4107faa8d3613b1a5d17e445e075290d2f2f3cdbcab11724d
MD5 aae649fded70ce1e061787bc0bbaefbf
BLAKE2b-256 460a3b0012b46d5f211163250fe9cf720a37d7ee55da53619387507fb74807cc

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.19-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