Skip to content

Latest commit

 

History

History
199 lines (147 loc) · 6.8 KB

File metadata and controls

199 lines (147 loc) · 6.8 KB

python-sdk

A Dagger module for managing Dagger modules that use the Python SDK.

SDK-specific module authoring (scaffolding new modules, language build config, codegen) lives in modules like this one. Under the CLI 1.0 init contract the engine drives the SDK: this module exposes initModule and targetRuntime, and the engine merges the SDK-owned files with its own workspace bookkeeping. Shared, language-agnostic operations — editing a module's dependencies or its required engine version — are owned by the core CLI (dagger module deps, dagger module engine) and are no longer part of this module's surface.

It uses the engine's native Workspace and ModuleSource APIs directly.

What lives here

Path What it is
python-sdk.dang, mod.dang, templates/ authoring: initModule, generate, config, discovery
sdk/ the dagger-io client library and code generator
runtime/ the module runtime the engine calls to run a module

Code generation happens at dagger generate, through this module's @generate hook, which runs the code generator in sdk/ and vendors the result into the module. The runtime never generates: it builds a module from its committed generated files, so there is no codegen step in a cold dagger call, and a module that has not been generated fails with an actionable error rather than being silently regenerated.

Pre-1.0 dagger.json modules are the exception: they keep being generated and run by the Python SDK baked into the engine, exactly as before.

Two runtimes, one name

Python modules reach one of two implementations, and which one is decided by the module's config format:

  • Legacy — a dagger.json with "sdk": {"source": "python"} resolves to the runtime baked into the engine (dagger/dagger's sdk/python), which still generates bindings at module load. Nothing about those modules changes, and they need no migration.
  • Modern — a dagger-module.toml can point [runtime] source at this repository's runtime/, which is the no-codegen path above. Either a module ref or a path relative to the module works, for both dagger generate and dagger call.

The engine resolves the short name python to exactly one target, the engine-baked runtime, so the modern path is reached by module ref rather than by name. targetRuntime — what dagger module init python writes into a new module — is therefore still python today; it moves to github.com/dagger/python-sdk/runtime in a follow-up, once runtime/ exists on the default branch for that ref to resolve to. See future/done/self-contained-python-sdk.md for the full reasoning and for the engine change that would let one name serve both.

Trying this repository's runtime

targetRuntime still writes python, so a module created today runs on the engine's runtime. To move one onto this repository's runtime, point it there by hand:

# <module>/dagger-module.toml
[runtime]
source = "github.com/dagger/python-sdk/runtime"

Then dagger generate the module and dagger call it as usual. The generated files are identical either way — generation is this SDK's regardless of which runtime runs the module — so switching back is just editing the line again.

Within this repository, a path relative to the module works too, which is how the end-to-end fixture exercises the runtime before the ref exists.

Install

From your workspace root:

dagger install github.com/dagger/python-sdk

After install, the module is available in dagger call as python-sdk.

Calls that return a Changeset will print the diff and prompt you to confirm before writing anything to your workspace.

Create a new module

With a CLI that supports the 1.0 init contract, the engine dispatches to this SDK's initModule:

dagger module init python my-module

initModule only seeds the SDK-owned template files; the engine writes the module config and workspace entries. Run generate afterwards to produce the generated SDK bindings.

The SDK-specific args below become typed flags on dagger module init python:

dagger module init python my-module --template legacy
dagger module init python my-module \
    --python-version 3.13 \
    --use-uv=false \
    --base-image python:3.13-slim

--template picks a starter template: default (a small working module) when you pass nothing, empty for a bare object class, or legacy for a container-echo example. The three pyproject.toml flags are optional; by default the template's Python version is used, uv is enabled, and no base image override is written.

You can also call the function directly for testing. path is required (the engine supplies it in the dispatched path):

dagger call python-sdk init-module --name my-module --path .dagger/modules/my-module

Configure an existing module

Read the current configuration. Settings that are not explicitly written to pyproject.toml are reported as null rather than guessed:

dagger call python-sdk mod --path my-module config get

Select a single value:

dagger call python-sdk mod --path my-module config get python-version
dagger call python-sdk mod --path my-module config get use-uv
dagger call python-sdk mod --path my-module config get base-image

Change one or more values at once (prints a diff to confirm before writing). Each flag is optional; omitting one leaves that setting untouched:

dagger call python-sdk mod --path my-module config set \
    --python-version 3.13 \
    --use-uv=false \
    --base-image python:3.13-slim

Generate SDK files

For a single module:

dagger call python-sdk mod --path my-module generate

For every Python SDK module in the workspace (skipping any with a .dagger-python-sdk-skip-generate marker at or above the module root):

dagger call python-sdk generate-all

Manage dependencies and the engine version

Editing a module's dependencies or its required engine version is identical across SDKs, so the core CLI owns it:

dagger module deps add github.com/some/module
dagger module engine require-latest

Discover modules in a workspace

# Every Python SDK module under the workspace
dagger call python-sdk modules path

Note

modules and generate-all read the modules registered under modules.<sdk>.as-sdk.modules, which the engine owns and narrows to the caller's cwd. Nothing scans module config files.

See python-sdk.dang for the full type surface.

Skipping generation

To exclude a directory tree from generate-all, drop an empty .dagger-python-sdk-skip-generate file at or above the module root. Useful for fixtures, vendored modules, or anything you don't want regenerated in bulk.

touch some/fixture/.dagger-python-sdk-skip-generate