Zuke for Python: author your build as typed Python, run it on the Zuke engine. Your build and your CI are one typed file — and your agent can run it.
Zuke is a code-first, strongly-typed build automation system: a build is a class whose fields are targets, dependencies are references the type checker sees, and the same file generates your CI and serves your build to AI agents. This package brings that model to Python. Write the build as typed Python, and the Zuke engine runs it: scheduling, retries, timeouts, cancellation, durable runs, locks, caching, services, CI generation, the MCP server and every tool wrapper live there, implemented once. This package is the thin SDK that describes your build to the engine and runs your target bodies when asked.
Five minutes to a typed Python build
1. Install the zuke CLI — pick one. Every route is the same CLI; see the
main repository's install guide.
deno install -A -g -n zuke jsr:@zuke/cli # any OS, with Deno
brew install zuke-build/tap/zuke # macOS, Linux
choco install zuke # Windows
2. Scaffold a Python project and run it:
zuke setup --sdk python # build.py, zuke.json pinning @zuke/engine, the launchers
zuke # run the build
zuke --list # every target, with its description and dependencies
You need uv; the scaffolded build.py carries
inline script metadata, so uv run build.py installs this package by itself,
with no project file of its own. Here is a build after replacing the sample
target with real work:
from zuke import Build, ci, parameter, run, target
from zuke.tools.docker import DockerTasks
class CI(Build):
tag = parameter("image tag").default("dev")
pipeline = ci().path(".github/workflows/ci.yml")
lint = (
target().description("ruff").executes(lambda ctx: ctx.sh("ruff", "check", "."))
)
test = target().depends_on(lint).executes(lambda ctx: ctx.sh("pytest", "-q"))
image = (
target()
.depends_on(test)
.executes(
lambda ctx: DockerTasks.build(
ctx, lambda s: s.tag(f"app:{tag.value}").file("Dockerfile")
)
)
)
run(CI)
zuke image runs lint, test and image in order, every command spawned by
the engine. zuke graph --output=html draws the graph, zuke generate-ci
writes the workflow the ci() field declares, and zuke mcp serves the whole
build to an agent as typed tools.
Why Zuke for Python
- Typed, refactor-safe dependencies.
depends_on(lint)is a reference to the sibling field, not a string: pyright sees it, a rename moves every use, and a typo is an error before anything runs. - Every tool, typed.
zuke.toolsholds a facade for each of the engine's 50+ wrappers — Docker, Kubernetes, Terraform, uv-adjacent tooling, the cloud CLIs, the AI reviewers — generated from the engine's own tool spec, so the Python surface matches the TypeScript one setter for setter. - One engine, every guarantee. Argv-only command execution, output capture and secret redaction, dry runs, timeouts and cancellation, durable run records with resume, cross-run locks, caching and services are all done once, in the engine, for every SDK. The Python side cannot drift from them.
- Never write CI YAML again. Declare the pipeline in the build and the
engine renders GitHub Actions, GitLab CI, Azure Pipelines or Bitbucket YAML;
generate-ci --checkfails CI when the committed file drifts. - Let your agent run the build.
zuke mcpserves your targets, parameters and graph over the Model Context Protocol, exactly as for a TypeScript build. - No runtime dependencies. The package is the standard library only, and strict-typed end to end.
Install
| What | How |
|---|---|
The zuke CLI |
deno install -A -g -n zuke jsr:@zuke/cli, brew install zuke-build/tap/zuke, choco install zuke |
| This package, into an existing project | uv add --dev zuke, or pip install zuke |
| A new project | zuke setup --sdk python, which writes build.py, zuke.json and the launchers |
Python 3.12 or newer. The engine runs on Deno: the zuke CLI finds or
installs it, and so do the committed ./zuke and zuke.ps1 launchers, which
download a pinned, checksum-verified Deno on first use. zuke.json pins the
exact @zuke/engine release a project runs on; zuke upgrade --engine moves
it.
On a machine without the CLI, such as a CI runner, the launchers run the build
the same way: ./zuke ci, or ./zuke.ps1 ci on Windows. The generated
workflows call them.
How it works
zuke <target> ─▶ @zuke/engine (the pinned release, on Deno)
│ starts the worker zuke.json names: uv run build.py
▼
build.py ◀── JSON-RPC 2.0 over loopback ──▶ engine
(this SDK) build.describe, target.run, scheduling, exec,
exec, tool.call, state, … wrappers, CI, MCP
The engine starts your build file as a worker and asks it for the graph.
When a target's turn comes, the engine asks the worker to run its body; the
body's ctx.sh(...) and every *Tasks call travel back to the engine, which
spawns the process or runs the real wrapper under the run's dry-run, redaction
and cancellation. The worker's stdout and stderr become log lines, so a stray
print cannot corrupt the protocol. The protocol and its conformance cases are
defined in the main repository
(packages/engine); this package replays
every case of the engine release it pins.
The authoring surface
target() carries every setting the engine schedules by (depends_on,
retry, timeout, before, after, triggers, on_failure, …);
parameter() has the string, number, boolean and list kinds, with .value
resolved by the engine from flags and environment variables, and .secret()
redacts one everywhere; group() names a parallel batch; service() declares a
service with start, ready and stop phases; ci() declares a CI file; and
run() makes the file a worker.
A body gets a ctx: await ctx.sh(...) runs a command through the engine and
raises CommandError on a non-zero code; ctx.state and ctx.state_of(...)
read and write durable state; ctx.outcome_of, ctx.outcomes, ctx.summary,
ctx.secret, ctx.log, ctx.plan and ctx.signals are the rest of what the
engine serves a body. A target may declare .condition(...), .cache_key(...),
.lock(...), .waits_for(...) and .validate_during(...), and a Build
overrides on_start, on_target_start, on_target_end and on_finish for
hooks.
zuke.tools.<wrapper> is a facade per engine wrapper — zuke.tools.docker,
zuke.tools.deno, zuke.tools.gh and the rest. DockerTasks.build(ctx, lambda s: ...) records the setters the lambda calls and sends the engine one
tool.call, which runs the real wrapper with the worker's environment and
directory. The full catalogue, with every task and setting, is the main
repository's tool reference.
Supply chain
Every release is built by this repository's own Zuke build and uploaded to PyPI
with trusted publishing: no API
token exists. From 1.0.1, each file also carries a
PEP 740 provenance attestation, signed from
the release job's identity, which PyPI verifies back to
zuke-build/zuke-python's release.yml; see the Security tab of a release
on PyPI. Actions are pinned by commit SHA, the
engine and every wrapper it loads run frozen against the committed deno.lock,
and uv.lock locks the development environment. See
SECURITY.md.
Documentation
The documentation lives in the main repository:
- Getting started — install, scaffold
(including
zuke setup --sdk python), and a first build. - Core concepts — the build, target and graph model and its execution semantics, the same for every SDK.
- Tools — every wrapper's tasks and settings.
- CLI reference — the
zukecommand and a build's own CLI. - MCP server, Caching, Services, Durable run state and Cross-run locks.
- The engine and its protocol — how any language hosts a build.
The Python surface itself is documented by its docstrings, and pyright and your
editor read them. The website renders them as the
Python API reference, with a
Python guide beside it: zuke api_reference
generates the reference from the docstrings, and each release syncs it to the
website.
Development
uv is the only tool you need.
uv sync # the locked environment
zuke ci # the gate: format check, lint, pyright strict, tests at 95%+
zuke --list # every target of build.py, this repository's own Zuke build
The gate is itself a Zuke build, build.py, run by @zuke/engine at the
version zuke.json pins; ./zuke ci runs the same gate without the CLI, and
CI runs it on Ubuntu, macOS and Windows. The tool facades are generated from the
engine's tool spec, vendored under spec/, and facades_check fails the gate
when they drift. The engine, every wrapper it imports, and their @zuke/core
run frozen against deno.lock; zuke lock rewrites it. The same AI reviewers
the main repository runs review this repository's pull requests, from
build.py's review target through zuke.tools.ai: the SDK's build is
reviewed by the SDK.
Contributing
Contributions are welcome! Start with CONTRIBUTING.md
for the workflow, and please be mindful of the
Code of Conduct. AGENTS.md
holds the coding standards — pyright strict, no Any or cast, 95%+ coverage,
hermetic tests. Every change starts with an issue. A change to the engine, the
protocol or a tool wrapper belongs in the main repository, and reaches
this one through the vendored spec and the pinned engine.
Security
zuke-python runs inside other people's build pipelines, so supply-chain
integrity is the primary concern. Please report a vulnerability privately,
through the Security tab's "Report a vulnerability"; see
SECURITY.md for the posture and the process, and
the main repository's policy for the engine.
License
MIT — see LICENSE.
Acknowledgements
- NUKE and its creator Matthias Koch — the code-first, strongly-typed build model Zuke is an homage to.
- uv, Ruff and pyright — the toolchain this package is built, linted and type-checked with.
- Deno and JSR, which the engine runs on and ships from, and PyPI and the PyPA, whose trusted publishing and attestations sign this package.
Community & contact
Questions, ideas, or just want to say hi? Open an issue for the Python side, or one in the main repository for everything else, or reach out:
Swag, sponsoring, star history & contributors
Swag
Zuke has a swag shop! Grab some Zuke-branded apparel and accessories and wear the build:
Sponsoring
If Zuke saves you time, you can support its development through GitHub Sponsors, Buy Me a Coffee or Patreon — the Sponsor button at the top of the repository lists them all.
Star history
If Zuke for Python is useful to you, consider starring this repository and the main one — it helps others find the project. ⭐
Contributors
Metadata
Release files for zuke 1.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| zuke-1.1.0.tar.gz | 513.5 kB | With provenance | Details for zuke-1.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| zuke-1.1.0-py3-none-any.whl | Python 3 | none | any | Details for zuke-1.1.0-py3-none-any.whl |
Total release size: 802.1 kB
Release files / zuke-1.1.0.tar.gz
| Download URL | zuke-1.1.0.tar.gz |
|---|---|
| Size | 513.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
48a297d03c18566279b2ad5ac0fcc81dd6cecc4533b0c3426b5d4461eeae2ca2
|
|
BLAKE2b-256 checksum How to use checksums |
372f8a9a98b9a44d93c46b7fa6331a2ee88a5d203ad1b9fb19121680e0300451
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.7 {"installer":{"name":"uv","version":"0.13.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 3, 2026.
Transparency logRelease files / zuke-1.1.0-py3-none-any.whl
| Download URL | zuke-1.1.0-py3-none-any.whl |
|---|---|
| Size | 288.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c3743ca218df0a2355b6e63ff1e4506ec482430b6c9ec2bfd068965c65017b78
|
|
BLAKE2b-256 checksum How to use checksums |
2dd769e6345d11f60a97e7abd71ca85e5ce9eabc9b1e882d3de565d4b16c4e54
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.13.7 {"installer":{"name":"uv","version":"0.13.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 3, 2026.
Transparency logSecurity for zuke 1.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for zuke-1.1.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Nov 3, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.