Repository navigation
Example CLI built on gfw-common, without Beam - #19
Merged
Merged
Conversation
tomaslink
added this pull request to stack #20
October 16, 2026 19:26
Base automatically changed from
PIPELINE-4672-shared-contributing-guide
to
main
October 16, 2026 19:29
init_project.py only renamed a fixed list of files, so any new module that imports the package by name (e.g. cli/main.py importing its commands) kept the template's name and broke after renaming. It now renames every .py file under src/<package>/ and tests/, except init_project's own tests, and also requirements-test.txt, whose compiled comments name the package.
Replaces the plain sys.argv entry point with gfw-common's CLI, laid out as in pipe-anchorages: - cli/main.py builds the CLI and registers the commands, with the shared --labels option. - cli/commands/hello.py: an example command that only defines its name, description and options, and delegates to its pipeline. - pipelines/hello/: its configuration (HelloConfig, a PipelineConfig) and its logic (run()). - config/hello/sample.yaml: an example configuration file. Command-line arguments take precedence over it, and it over the defaults. - Tests for the command (with run mocked), the configuration and the logic. - README: how to use the CLI and the new modules. gfw-common is installed without extras, so no Beam: the production image doesn't include it. gfw-common doesn't ship a py.typed marker, so mypy sees its classes as Any; subclassing them needs a type: ignore[misc].
tomaslink
force-pushed
the
PIPELINE-4673-example-cli-gfw-common
branch
from
October 16, 2026 19:29
b45f370 to
f030070
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PIPELINE-4673 · Stacked on #18 (merge that first).
Summary
Replaces the template's plain
sys.argventry point with an example CLI built on gfw-common, so new projects start from the standard pattern. No Beam: gfw-common is installed without extras, so the template also suits services.Layout (as in pipe-anchorages)
python-app-template hello --name GFW --times 2 --labels environment=development, or-c config/hello/sample.yaml. Command-line arguments override the config file, and the config file overrides the defaults.HelloConfiginheritsPipelineConfig(labels,from_namespace) and extends its validation (times >= 1).run()receives the typed config, not the CLI'sSimpleNamespace: the command converts the CLI input at the edge (HelloConfig.from_namespace), sorunhas a typed signature that mypy checks, and other callers (DAGs, scripts, tests) build a validatedHelloConfigdirectly. This differs from pipe-anchorages, whererunconverts the namespace itself; the template is meant to be the reference going forward.runmocked (defaults, options, config file precedence), the configuration and the logic as plain functions.config/directory.init_project.py: rename every Python file of the package and the testsIt only renamed a fixed list of files, so the new modules that import the package by name would have broken after renaming (reproduced: 6 files kept
python_app_template). It now renames every.pyfile undersrc/<package>/andtests/(except its own tests, which use the template's name on purpose), andrequirements-test.txt, whose compiled comments name the package.Note
gfw-common doesn't ship a
py.typedmarker, so mypy treats its classes asAny; subclassing them under strict mypy needs# type: ignore[misc]. Follow-up: addpy.typedto gfw-common.Verification
pytest: 18 passed, 100% coverage;flake8,ruff,black,mypy,codespell: clean.make docker-build && make docker-test: 11 passed (the image excludesinit_project's tests). The production image runspython-app-template hello, and doesn't includeapache_beam(148 MB).python init_project.py my-serviceon a copy: its 18 tests pass,my-service hello -c config/hello/sample.yamlgreets twice, and the only remainingpython-app-templatestrings are the links to the shared contributing guide.🤖 Generated with Claude Code