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.20.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.20-cp314-cp314-win_amd64.whl (533.8 kB view details)

Uploaded CPython 3.14Windows x86-64

camas-0.1.20-cp314-cp314-musllinux_1_2_x86_64.whl (970.1 kB view details)

Uploaded CPython 3.14musllinux: musl 1.2+ x86-64

camas-0.1.20-cp314-cp314-musllinux_1_2_aarch64.whl (956.6 kB view details)

Uploaded CPython 3.14musllinux: musl 1.2+ ARM64

camas-0.1.20-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (975.5 kB view details)

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

camas-0.1.20-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl (943.2 kB view details)

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

camas-0.1.20-cp314-cp314-macosx_11_0_arm64.whl (644.7 kB view details)

Uploaded CPython 3.14macOS 11.0+ ARM64

camas-0.1.20-cp313-cp313-win_amd64.whl (525.9 kB view details)

Uploaded CPython 3.13Windows x86-64

camas-0.1.20-cp313-cp313-musllinux_1_2_x86_64.whl (964.6 kB view details)

Uploaded CPython 3.13musllinux: musl 1.2+ x86-64

camas-0.1.20-cp313-cp313-musllinux_1_2_aarch64.whl (946.5 kB view details)

Uploaded CPython 3.13musllinux: musl 1.2+ ARM64

camas-0.1.20-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (969.8 kB view details)

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

camas-0.1.20-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl (933.6 kB view details)

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

camas-0.1.20-cp313-cp313-macosx_11_0_arm64.whl (650.3 kB view details)

Uploaded CPython 3.13macOS 11.0+ ARM64

camas-0.1.20-cp312-cp312-win_amd64.whl (526.2 kB view details)

Uploaded CPython 3.12Windows x86-64

camas-0.1.20-cp312-cp312-musllinux_1_2_x86_64.whl (970.4 kB view details)

Uploaded CPython 3.12musllinux: musl 1.2+ x86-64

camas-0.1.20-cp312-cp312-musllinux_1_2_aarch64.whl (953.6 kB view details)

Uploaded CPython 3.12musllinux: musl 1.2+ ARM64

camas-0.1.20-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (976.2 kB view details)

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

camas-0.1.20-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl (940.4 kB view details)

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

camas-0.1.20-cp312-cp312-macosx_11_0_arm64.whl (645.7 kB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

camas-0.1.20-cp311-cp311-win_amd64.whl (523.6 kB view details)

Uploaded CPython 3.11Windows x86-64

camas-0.1.20-cp311-cp311-musllinux_1_2_x86_64.whl (923.4 kB view details)

Uploaded CPython 3.11musllinux: musl 1.2+ x86-64

camas-0.1.20-cp311-cp311-musllinux_1_2_aarch64.whl (914.2 kB view details)

Uploaded CPython 3.11musllinux: musl 1.2+ ARM64

camas-0.1.20-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl (931.4 kB view details)

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

camas-0.1.20-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl (900.9 kB view details)

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

camas-0.1.20-cp311-cp311-macosx_11_0_arm64.whl (641.7 kB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

File details

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

File metadata

  • Download URL: camas-0.1.20.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.20.tar.gz
Algorithm Hash digest
SHA256 7f815ae382fcb5a0f674361a275d96bf430590716149b6d0e8df5964450802d6
MD5 3e921312a0dae35617378739e15a92b5
BLAKE2b-256 513a7606bf46c452bcacd3acb02198b80e2868b1c40cd5e915644b060a68348a

See more details on using hashes here.

Provenance

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

File metadata

  • Download URL: camas-0.1.20-cp314-cp314-win_amd64.whl
  • Upload date:
  • Size: 533.8 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.20-cp314-cp314-win_amd64.whl
Algorithm Hash digest
SHA256 9defc41bbf23b5955703ab6b6b704ad84757cab74a43130694f815b711a7294b
MD5 ac360675fe3b390e6dd1ac1e5e284040
BLAKE2b-256 3309fa799c56948acde6eaf90d086047bc440ba022471f31435f06284479115b

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for camas-0.1.20-cp314-cp314-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 415a5c09dcc9af6bc3cf61459852a280f4cbfb6cc9980fdb2d0bf1e948a46aae
MD5 762ca045bb4eeec78988cc7274d25760
BLAKE2b-256 a61922a2b7bf8d0442a2364534901ec4812cd894f56913db4ef5a450599571ed

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for camas-0.1.20-cp314-cp314-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 38b703fb4e0d3dc469b6b60c25b646668f0a01c36531694e251a2b7d48c6654e
MD5 441ac23bb2325532243e41502da5ab2e
BLAKE2b-256 c791a4e905cb813ae518e5e919cc5364ad8e0adc56af8936720d693f6996812b

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.20-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.20-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.20-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 b4380464d5e63940e9cfa43ca7ff8a9eefa7b8b1c1b87b9dd2794c0c1b5ac4cc
MD5 3d3fb84f4d5c30e789ea23c23d3500e2
BLAKE2b-256 b7392e9772638213db0049f0227fea31bf6763f7de3dd7092a869a8850f77978

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for camas-0.1.20-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 dac031b9a22bdba74d9b965ffffee528af68dbbf2b0fbb369dc4b7de77ec4ce1
MD5 853fb942d82a7ac219c35021e811ef1e
BLAKE2b-256 7078988552cbc005d464eeb5df587c35f1b6e34d9df72391a937076a442d9a39

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for camas-0.1.20-cp314-cp314-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 68bfac05a15971c390ed8a82b19888f05f4a1649cc33b9255d648ab769a089de
MD5 248d0319e963e5e2a2c4f0efd134b631
BLAKE2b-256 8c0c6057930abb35b44b54577a26d3fa9f921dec74395996bdbd5c856d78273c

See more details on using hashes here.

Provenance

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

File metadata

  • Download URL: camas-0.1.20-cp313-cp313-win_amd64.whl
  • Upload date:
  • Size: 525.9 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.20-cp313-cp313-win_amd64.whl
Algorithm Hash digest
SHA256 468677165e9724f3460cb664c04c2e5f1e0c1f677e6998c150d31d4829849ca1
MD5 39f77b76ce078a73b254b602261cde04
BLAKE2b-256 9e93ff2f0052effec62e212974d2f66ed0c8f1077b33eea9c57d41a869bf3dce

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for camas-0.1.20-cp313-cp313-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 0350d3e7bb5ba5e46b08e79bc0f761d018f9f68909b967af746f02b30aa340e5
MD5 eed1ea69c77c4f1d72f89ff505859b07
BLAKE2b-256 27083fdf521901b2988731a088d9395d04275fabdc9183deec98c349474eecf5

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for camas-0.1.20-cp313-cp313-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 116e23b5aca0fd49ef848cbf2c36676d3843355e7648bed0d41703f0e307e8f1
MD5 60d0feb79d660b484a4d72457dfdf787
BLAKE2b-256 a3149c616294d0c3661fc43fbe0b1de5ef846d3dffb3379e9cf42c27474a63af

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.20-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.20-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.20-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 f581978ff0b82eb1df233707520ccf4fff0cb64c86f3885ce7eb4fdf5d6a8192
MD5 322cc544318ae542e76d8959117bc741
BLAKE2b-256 d882960aa3979dd530e6cf74d6eb458ec003c4edab11bdaa5bee9b7db1426846

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for camas-0.1.20-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 c01c94f61b55c3e9026833065f2f7a59faebe68e63cfd8c0d01bc23317c760c6
MD5 0234bbaa544f4ef2ef6ab8c312465810
BLAKE2b-256 9fa757f21d2b191e546e9c659cb808d18ad6fdf75d1477d178e912aaa10cc095

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for camas-0.1.20-cp313-cp313-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 512457e830fa0adb0f8ca23261b995de897677a67e1323a42729abdc46720a3a
MD5 222aa21b3d77bb4854224b857ae7037d
BLAKE2b-256 155477b078cc6b628562e78becf3b0f96e147e6068634e837925bd55a0f0fdf4

See more details on using hashes here.

Provenance

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

File metadata

  • Download URL: camas-0.1.20-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 526.2 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.20-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 0f6779070d20b329bb3df1a6aa4998e3ffce42f49d39aa3f1c5eaad9676d7293
MD5 cf371aa66601befe725f1cefaf10aabb
BLAKE2b-256 724b617f5fdcfd16e7c88a05567740537358a8c475e66a86ad6e36916c4222b0

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for camas-0.1.20-cp312-cp312-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 ce05786d7eed2e76e33bdc8f1c1e9a1cbf88278c259f4507bbb36f5d8570fe8e
MD5 a7cd3089cae8df8934631d7cc63de51b
BLAKE2b-256 83606b177b80684ecda5b5bea71c765ad3a9f64d454e87d2178ce0ab9ca03039

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for camas-0.1.20-cp312-cp312-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 1b70fd0af20bb945415d11516cd6bbfab6d075d70eb1b41588329fdd53b5d50a
MD5 cdda4e02b183167360195868700cc526
BLAKE2b-256 dd63ce72dfe2f8928e885579c7e5905280b8011045f46e62c485d3cdea6f159e

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.20-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.20-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.20-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 540134b43e5fb6f70a1fac11a3b5cc9f074e0946ea1f7010b203d36e7fa7148f
MD5 6778a8bbe8a104f9a063e2bcd3e21761
BLAKE2b-256 a4bb92123b23cc1f14f2728898c105c748a3f011b10559958fc6d7e076be4447

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for camas-0.1.20-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 60fe4410081ea3901985156f0b113047d44fb5e6a229622465704732dedb5e60
MD5 957e0e961e761eb32d1a0de620fb7fd9
BLAKE2b-256 5232b45c570753d9f00bb70374b5baa6c7c8d443221782a5c01e9716d5a02602

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for camas-0.1.20-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 fa247c6ca84e55fd8ce82e83c37535b46031c575368b00035f518db7c872173d
MD5 4d6d059e30b616419271ac56d7a5f61d
BLAKE2b-256 605cfe3f782cdbfafedb100bb48db37b0ec1c110ab2746eed4dea1fb7485f77b

See more details on using hashes here.

Provenance

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

File metadata

  • Download URL: camas-0.1.20-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 523.6 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.20-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 de1b6d9dc27d2b5b50c702b47b00e2e826fb6932626366720da410c54f253977
MD5 6f158140316cd7e9e6865250e2d68eff
BLAKE2b-256 8a51819947e150f224cd1e119fad9b701df783c13d2d4a270865769158010f42

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for camas-0.1.20-cp311-cp311-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 454d18725ae11d63f8093f61c49e83b3767dc6b71a229d90f048891cc43542ff
MD5 ae08ae6380f536ee80c869729f77e8c3
BLAKE2b-256 dc0b18f83ba592181a2dd2418a104b24c92863da29cb7ac00da008b9ad3ac0ad

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for camas-0.1.20-cp311-cp311-musllinux_1_2_aarch64.whl
Algorithm Hash digest
SHA256 53f0619386bb681fb7d8fa14cb7d9c4becee14938e79c2dae667c21c60f2f718
MD5 97960328abd83395be3575731ea16e19
BLAKE2b-256 75e378967a321b8c05414f64e851e6cd444f72b27b941eee5d27f92d4cf8b5da

See more details on using hashes here.

Provenance

The following attestation bundles were made for camas-0.1.20-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.20-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.20-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 4535bde0addbd67b8521a5810e2fd91db2c797e5518f71629abb056929e7e54f
MD5 ab34bfdd2b2d4ecd2a61118d0fe4ed6f
BLAKE2b-256 c99eca647a884b0673447b6c69d88b92aca1be246a164f934143059b2aa29bf2

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for camas-0.1.20-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 97218e4f0013d997c44361862a6cabfc0457e1276137d3847095cd1c0a60facf
MD5 8870b9aac8453c8846806b13bbbcaa15
BLAKE2b-256 9349622858de97385e25c89c68fb36ce2f05575cded0c2f9dc5402e5eb516ea1

See more details on using hashes here.

Provenance

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

File metadata

File hashes

Hashes for camas-0.1.20-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 0659e9d75d61327ac9b1da4979120001672a6eee91837df2c2e9314ce56c0e6e
MD5 cd3169fdd42b39f3e3585b4967f1a207
BLAKE2b-256 1cd37c27f88599734aeaf647013292bb58c927fe0d2911db1f16381a49105e89

See more details on using hashes here.

Provenance

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