Skip to content

feat: ship a useful default Python init template#10

Open
grouville wants to merge 3 commits into
dagger:mainfrom
grouville:feat/default-template
Open

feat: ship a useful default Python init template#10
grouville wants to merge 3 commits into
dagger:mainfrom
grouville:feat/default-template

Conversation

@grouville

@grouville grouville commented Jul 22, 2026

Copy link
Copy Markdown
Member

Why

Today, dagger module init python hello creates a valid module whose object only contains pass. It works, but it does not show a new user how to turn their workspace into something useful.

For the 1.0 experience tracked in dagger/dagger#13626, the default should be a small working example. This follows the direction established by dagger/typescript-sdk#10.

What changes

The new default stores a filtered view of the caller's workspace and exposes a container function with that source mounted at /src. It uses Alpine 3.24 by default, while keeping the image configurable.

The template stays deliberately generic: it does not assume the workspace is a Python project, uses uv, or has a particular build command. uv is only used to package the generated Dagger module.

The previous blank template is now available as --template empty. legacy is unchanged, and an explicitly empty template value continues to select the default for compatibility.

The generated project files also move to Python 3.14 and accept uv_build releases below 0.12. The lower bound remains compatible with the uv version already bundled in the engine.

Why create instead of __init__

The template uses the Python SDK's supported alternate create constructor. It receives the caller's workspace and converts it into the fields Dagger stores between function calls. This keeps the user-facing workspace input separate from the state Dagger needs to restore later.

Try it

From an empty Git repository:

dagger sdk install github.com/grouville/python-sdk@feat/default-template --name python -y
dagger module init python hello -y
dagger api functions hello
dagger api call hello container \
  with-exec --args sh --args -c --args 'test -f /src/dagger.toml && pwd' \
  stdout

dagger api functions hello should list container, and the final command should print /src.

To check the blank template:

dagger module init python blank --template empty -y
sed -n '1,20p' .dagger/modules/blank/src/blank/__init__.py

The generated Blank class should contain only pass.

Verification

dagger check e-2-e:template-check
dagger check

All 12 checks pass against v1.0.0-beta.7 and the locally rebuilt engine from dagger/dagger@7a6730c178228b4a3a8273664d319578892b7fe1. A fresh generated module also returned Alpine 3.24.1 when invoked with the beta.7 CLI.

@grouville
grouville requested a review from TomChv July 22, 2026 22:36
@grouville
grouville force-pushed the feat/default-template branch from e4168db to fc92962 Compare July 22, 2026 22:43
@grouville
grouville requested a review from kpenfound July 22, 2026 23:55
@grouville
grouville force-pushed the feat/default-template branch from fc92962 to 3f513fe Compare July 23, 2026 00:10
`dagger module init python` currently generates an empty object. It is a
valid module, but it does not give users a useful starting point or show how
a workspace becomes a container.

Generate a small working module by default. It keeps the workspace source,
lets users choose the base image, and exposes a container function with the
source mounted at `/src`.

Python needs the public `create` method because Dagger later rebuilds the
object from its fields. Keeping the generated `__init__` available makes that
reconstruction work when another function is called.

The previous blank template remains available as `empty`, while `legacy`
stays unchanged. Name the workspace argument `ws` to avoid clashing with the
CLI's top-level `--workspace` flag.

Signed-off-by: Guillaume de Rouville <guillaume@dagger.io>
The init command now has two useful starting points: the working default and
the blank `empty` template. Cover both through `initModule`, including the
existing behavior where an explicitly empty template name selects the
default.

Check the generated source rather than the template helpers so the test sees
what users actually receive. Also call the generated container function. This
catches a Python-specific failure where the module loads correctly but fails
when Dagger rebuilds the object before the next function call.

Keep the expected and unwanted snippets together so reviewers can read the
generated source contract without working through repeated assertions.

Signed-off-by: Guillaume de Rouville <guillaume@dagger.io>
Bring newly generated projects in line with the versions we support today:
Python 3.14, uv_build through the 0.11 line, and Alpine 3.24 for the new
default container.

Keep uv_build's lower bound at 0.8.4 because the engine already includes a
compatible version. This avoids an unnecessary download while still allowing
current releases below 0.12.

Signed-off-by: Guillaume de Rouville <guillaume@dagger.io>
@grouville
grouville force-pushed the feat/default-template branch from 3f513fe to 6b06cbc Compare July 23, 2026 00:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant