CDTOOL-1649: Add Python Language Support - #1811

Merged
anthony-gomez-fastly merged 14 commits into
mainfrom
posborne/python-language-support
Aug 4, 2026
Merged

CDTOOL-1649: Add Python Language Support#1811
anthony-gomez-fastly merged 14 commits into
mainfrom
posborne/python-language-support

Conversation

@posborne

Copy link
Copy Markdown
Member

This change introduces support for Python on Compute to the fastly CLI. For dependencies, after exploring a few different options it was determined that this responsibility was best left to the fastly-compute-py which executes at a better point in time to correctly determine what is part of a Python services dependency graph (in addition to separation of concerns).

The way this dependency information is passed along, dependent on fastly/compute-sdk-python#89, is that the information is written directly into the WASM component as part of the fastly-compute-py build process. Other information may be injected similarly. This approach may be used by other SDKs/tooling in the future should it make sense or be used directly for "Other" languages.

Discussion is ongoing for the approach we'll follow for Python SDK starter templates but that is not included here as they are not available.

Modify the metadata annotation step to read and preserve any fastly_data
already embedded in the Wasm binary (e.g. by language-specific build tools
like python). This allows build tools to supply package info directly while
the CLI dynamically fills in remaining fields (like cloned repository info).
Add configuration, toolchain parsing, version validation, and build scaffolding
for Python projects inside the compute environment. Host Python >= 3.11 and uv
are utilized as standard toolchain constraints.
Ensure PromptForStarterKit does not index out-of-bounds when there are no
configured starter kits for a language. Instead, prompt the user for a
template git URL directly, or fail gracefully if non-interactive.
@posborne
posborne requested a review from a team as a code ownerJune 3, 2026 19:25
Use 0600 permissions for mock WASM files and add gosec ignore directives for
mock executable creation.
Comment threadCHANGELOG.md Outdated
@anthony-gomez-fastly

Copy link
Copy Markdown
Member

is it worth writing any tests in pkg/commands/compute/build_test.go for python?

Co-authored-by: Anthony Gomez <anthony.gomez@fastly.com>
@posborne

Copy link
Copy Markdown
MemberAuthor

is it worth writing any tests in pkg/commands/compute/build_test.go for python?

Yeah, would definitely be worthwhile I think. I'll work on getting that added.

I also slapped a "DO NOT MERGE YET" label on this for now until the dust settles on our approach for python starter kits and fastly/compute-sdk-python#89. I think this could merge without that PR but I'll want to verify that first.

Introduce TestBuildPython to build_test.go covering:
- Handling missing fastly.toml manifest
- Handling of typical build-time failures
- Dependency checks
- Basic python example
@kpflemingkpfleming changed the title Add Python Language SupportCDTOOL-1649: Add Python Language SupportJun 15, 2026
Comment threadCHANGELOG.md Outdated
Comment threadpkg/commands/compute/init.go Outdated
Comment threadpkg/commands/compute/build.go Outdated
Comment threadpkg/commands/compute/language_python.go Outdated
The entry was under the already-released v15.2.0 section. Also aligns
the PR link formatting with the surrounding entries.
text.Input takes variadic validators, so omitting the argument is the
way to skip validation.
Seeding the whole DataCollection from the binary let a build tool's
script_info, machine_info and build_info override fields the CLI owns.
The CLI now always writes those itself and reads back only the package
list, which is the one thing it cannot collect for Python.
The read is also gated on the language reporting no dependencies of its
own, so the extra `wasm-tools metadata show` subprocess no longer runs
for Rust, Go and JavaScript.
Silently falling back to a hardcoded ">= 3.11" hid a broken or outdated
CLI config and could validate against a constraint we never shipped.
@kailan

Copy link
Copy Markdown
Member

Review feedback is addressed across four commits (3bc678f, c97db52, d360125, d54cbf2). Verified end-to-end by building the CLI and running compute build against a real Python project — the missing-constraint path produces the new error and remediation, and the happy path builds pkg/test.tar.gz with correct merged metadata.

Three things worth flagging before this merges:

1. fastly-compute-py dependency metadata is merged but not released. compute-sdk-python#89 landed on main on 2026-06-05, but the latest tag/release is still v0.1.2 (2026-06-03), and PyPI fastly-compute tops out at 0.1.2. There are 5 unreleased commits on main ahead of that tag.

I confirmed this empirically: running uv run fastly-compute-py build against the pinned fastly-compute==0.1.2 in our testdata produces a producers section containing only language, processed-by and sdk — no fastly_data key. So the package_info read-back path in AnnotateWasmBinaryLong is currently dead code against every released version of the build tool. It's correct, just unexercised until an SDK release goes out.

The good news is the shapes line up: dependencies.rs serialises {"package_info":{"packages":{...}}}, and lib.rs pushes it as a processed-by / fastly_data pair — exactly what readExistingPackageInfo parses. So this should light up on its own once the SDK ships, no CLI change needed. Might be worth cutting that release first so we can validate the merge against a real artifact rather than only the mocked unit test.

2. The embedded pkg/config/config.toml has no [language.python] section. Now that a missing toolchain_constraint is a hard error, a stock config makes every Python build fail. This is the same state cpp is in — scripts/config.sh copies .fastly/config.toml over it at release time — so it should resolve itself through the normal release path. Calling it out because the new error makes the consequence louder than it was for cpp, and it's worth confirming the release script covers it.

3. build_test.go tests for PythonTestBuildPython already exists on the branch (gated behind TEST_COMPUTE_BUILD / TEST_COMPUTE_BUILD_PYTHON), so I believe the earlier question about test coverage is resolved. Flagging in case you wanted something broader than what's there.

@anthony-gomez-fastlyanthony-gomez-fastly left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks you two!

@anthony-gomez-fastly
anthony-gomez-fastly enabled auto-merge (squash) August 4, 2026 15:19
@anthony-gomez-fastly
anthony-gomez-fastly merged commit f975ca4 into mainAug 4, 2026
19 of 23 checks passed
@anthony-gomez-fastly
anthony-gomez-fastly deleted the posborne/python-language-support branch August 4, 2026 15:25
kailan added a commit that referenced this pull request Aug 7, 2026
### Change summary
Fixes [CDTOOL-1707](https://fastly.atlassian.net/browse/CDTOOL-1707).
`fastly compute init --language python` reports that no starter kits
exist:
```
$ fastly compute init --language python --non-interactive
ERROR: no default starter kits configured for this language; please specify a template using the --from flag.
```
Interactively it prints _"No default starter kits are currently
configured for this language"_ and falls back to prompting for a
template git URL.
The starter kits embedded into the CLI binary are injected into
`pkg/config/config.toml` at build time by
[`./scripts/config.sh`](https://github.com/fastly/cli/blob/main/scripts/config.sh),
which holds its own hardcoded list of starter kit repositories. Python
language support (#1811) added `[language.python]` to
`.fastly/config.toml` and wired Python into `NewLanguages()`, but never
added `compute-starter-kit-python-default` to that list — so
`kits.Python` is empty and `PromptForStarterKit` takes its "no kits"
branch. `[language.python]` is present, so `compute build` is
unaffected; the gap is only starter kits.
This adds the repository to the list, plus a test asserting that every
language offered at the `compute init` prompt has at least one starter
kit in the static config, so the same drift is caught for the next
language we add. CI generates the config with `make config` before
running tests, so the test runs against the real generated config.
**Depends on fastly/compute-starter-kit-python-default#6**, which gives
the kit a human-readable `name` in its `fastly.toml`. `config.sh` copies
that field verbatim into the config, so until it merges the prompt
renders `[1] fastly-compute-python-app` rather than `[1] Default starter
for Python`. Nothing needs re-landing here once it merges — the config
is regenerated on each build — but this PR should not be released before
that one.
All Submissions:
* [x] Have you followed the guidelines in our Contributing document?
* [x] Have you checked to ensure there aren't other open [Pull
Requests](https://github.com/fastly/cli/pulls) for the same
update/change?
### Changes to Core Features:
* [x] Have you written new tests for your core changes, as applicable?
* [x] Have you successfully run tests with your changes locally?
Verified end-to-end after `make config`:
```
$ fastly compute init --language python --non-interactive
...
SUCCESS: Initialized package proj
```
### User Impact
Python users can init a project from the default starter kit instead of
having to supply `--from` or paste a git URL.
### Are there any considerations that need to be addressed for release?
No breaking changes and no `config_version` bump needed —
`NeedsUpdating` already rewrites local configs when the CLI version
changes, so existing users pick the new kit up on their next upgrade.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
[CDTOOL-1707]:
https://fastly.atlassian.net/browse/CDTOOL-1707?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for freeto 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.

3 participants

@posborne@anthony-gomez-fastly@kailan
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

CDTOOL-1649: Add Python Language Support - #1811

Merged
anthony-gomez-fastly merged 14 commits into
mainfrom
posborne/python-language-support
Aug 4, 2026
Merged

CDTOOL-1649: Add Python Language Support#1811
anthony-gomez-fastly merged 14 commits into
mainfrom
posborne/python-language-support

Conversation

@posborne

Copy link
Copy Markdown
Member

This change introduces support for Python on Compute to the fastly CLI. For dependencies, after exploring a few different options it was determined that this responsibility was best left to the fastly-compute-py which executes at a better point in time to correctly determine what is part of a Python services dependency graph (in addition to separation of concerns).

The way this dependency information is passed along, dependent on fastly/compute-sdk-python#89, is that the information is written directly into the WASM component as part of the fastly-compute-py build process. Other information may be injected similarly. This approach may be used by other SDKs/tooling in the future should it make sense or be used directly for "Other" languages.

Discussion is ongoing for the approach we'll follow for Python SDK starter templates but that is not included here as they are not available.

Modify the metadata annotation step to read and preserve any fastly_data
already embedded in the Wasm binary (e.g. by language-specific build tools
like python). This allows build tools to supply package info directly while
the CLI dynamically fills in remaining fields (like cloned repository info).
Add configuration, toolchain parsing, version validation, and build scaffolding
for Python projects inside the compute environment. Host Python >= 3.11 and uv
are utilized as standard toolchain constraints.
Ensure PromptForStarterKit does not index out-of-bounds when there are no
configured starter kits for a language. Instead, prompt the user for a
template git URL directly, or fail gracefully if non-interactive.
@posborne
posborne requested a review from a team as a code ownerJune 3, 2026 19:25
Use 0600 permissions for mock WASM files and add gosec ignore directives for
mock executable creation.
Comment threadCHANGELOG.md Outdated
@anthony-gomez-fastly

Copy link
Copy Markdown
Member

is it worth writing any tests in pkg/commands/compute/build_test.go for python?

Co-authored-by: Anthony Gomez <anthony.gomez@fastly.com>
@posborne

Copy link
Copy Markdown
MemberAuthor

is it worth writing any tests in pkg/commands/compute/build_test.go for python?

Yeah, would definitely be worthwhile I think. I'll work on getting that added.

I also slapped a "DO NOT MERGE YET" label on this for now until the dust settles on our approach for python starter kits and fastly/compute-sdk-python#89. I think this could merge without that PR but I'll want to verify that first.

Introduce TestBuildPython to build_test.go covering:
- Handling missing fastly.toml manifest
- Handling of typical build-time failures
- Dependency checks
- Basic python example
@kpflemingkpfleming changed the title Add Python Language SupportCDTOOL-1649: Add Python Language SupportJun 15, 2026
Comment threadCHANGELOG.md Outdated
Comment threadpkg/commands/compute/init.go Outdated
Comment threadpkg/commands/compute/build.go Outdated
Comment threadpkg/commands/compute/language_python.go Outdated
The entry was under the already-released v15.2.0 section. Also aligns
the PR link formatting with the surrounding entries.
text.Input takes variadic validators, so omitting the argument is the
way to skip validation.
Seeding the whole DataCollection from the binary let a build tool's
script_info, machine_info and build_info override fields the CLI owns.
The CLI now always writes those itself and reads back only the package
list, which is the one thing it cannot collect for Python.
The read is also gated on the language reporting no dependencies of its
own, so the extra `wasm-tools metadata show` subprocess no longer runs
for Rust, Go and JavaScript.
Silently falling back to a hardcoded ">= 3.11" hid a broken or outdated
CLI config and could validate against a constraint we never shipped.
@kailan

Copy link
Copy Markdown
Member

Review feedback is addressed across four commits (3bc678f, c97db52, d360125, d54cbf2). Verified end-to-end by building the CLI and running compute build against a real Python project — the missing-constraint path produces the new error and remediation, and the happy path builds pkg/test.tar.gz with correct merged metadata.

Three things worth flagging before this merges:

1. fastly-compute-py dependency metadata is merged but not released. compute-sdk-python#89 landed on main on 2026-06-05, but the latest tag/release is still v0.1.2 (2026-06-03), and PyPI fastly-compute tops out at 0.1.2. There are 5 unreleased commits on main ahead of that tag.

I confirmed this empirically: running uv run fastly-compute-py build against the pinned fastly-compute==0.1.2 in our testdata produces a producers section containing only language, processed-by and sdk — no fastly_data key. So the package_info read-back path in AnnotateWasmBinaryLong is currently dead code against every released version of the build tool. It's correct, just unexercised until an SDK release goes out.

The good news is the shapes line up: dependencies.rs serialises {"package_info":{"packages":{...}}}, and lib.rs pushes it as a processed-by / fastly_data pair — exactly what readExistingPackageInfo parses. So this should light up on its own once the SDK ships, no CLI change needed. Might be worth cutting that release first so we can validate the merge against a real artifact rather than only the mocked unit test.

2. The embedded pkg/config/config.toml has no [language.python] section. Now that a missing toolchain_constraint is a hard error, a stock config makes every Python build fail. This is the same state cpp is in — scripts/config.sh copies .fastly/config.toml over it at release time — so it should resolve itself through the normal release path. Calling it out because the new error makes the consequence louder than it was for cpp, and it's worth confirming the release script covers it.

3. build_test.go tests for PythonTestBuildPython already exists on the branch (gated behind TEST_COMPUTE_BUILD / TEST_COMPUTE_BUILD_PYTHON), so I believe the earlier question about test coverage is resolved. Flagging in case you wanted something broader than what's there.

@anthony-gomez-fastlyanthony-gomez-fastly left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks you two!

@anthony-gomez-fastly
anthony-gomez-fastly enabled auto-merge (squash) August 4, 2026 15:19
@anthony-gomez-fastly
anthony-gomez-fastly merged commit f975ca4 into mainAug 4, 2026
19 of 23 checks passed
@anthony-gomez-fastly
anthony-gomez-fastly deleted the posborne/python-language-support branch August 4, 2026 15:25
kailan added a commit that referenced this pull request Aug 7, 2026
### Change summary
Fixes [CDTOOL-1707](https://fastly.atlassian.net/browse/CDTOOL-1707).
`fastly compute init --language python` reports that no starter kits
exist:
```
$ fastly compute init --language python --non-interactive
ERROR: no default starter kits configured for this language; please specify a template using the --from flag.
```
Interactively it prints _"No default starter kits are currently
configured for this language"_ and falls back to prompting for a
template git URL.
The starter kits embedded into the CLI binary are injected into
`pkg/config/config.toml` at build time by
[`./scripts/config.sh`](https://github.com/fastly/cli/blob/main/scripts/config.sh),
which holds its own hardcoded list of starter kit repositories. Python
language support (#1811) added `[language.python]` to
`.fastly/config.toml` and wired Python into `NewLanguages()`, but never
added `compute-starter-kit-python-default` to that list — so
`kits.Python` is empty and `PromptForStarterKit` takes its "no kits"
branch. `[language.python]` is present, so `compute build` is
unaffected; the gap is only starter kits.
This adds the repository to the list, plus a test asserting that every
language offered at the `compute init` prompt has at least one starter
kit in the static config, so the same drift is caught for the next
language we add. CI generates the config with `make config` before
running tests, so the test runs against the real generated config.
**Depends on fastly/compute-starter-kit-python-default#6**, which gives
the kit a human-readable `name` in its `fastly.toml`. `config.sh` copies
that field verbatim into the config, so until it merges the prompt
renders `[1] fastly-compute-python-app` rather than `[1] Default starter
for Python`. Nothing needs re-landing here once it merges — the config
is regenerated on each build — but this PR should not be released before
that one.
All Submissions:
* [x] Have you followed the guidelines in our Contributing document?
* [x] Have you checked to ensure there aren't other open [Pull
Requests](https://github.com/fastly/cli/pulls) for the same
update/change?
### Changes to Core Features:
* [x] Have you written new tests for your core changes, as applicable?
* [x] Have you successfully run tests with your changes locally?
Verified end-to-end after `make config`:
```
$ fastly compute init --language python --non-interactive
...
SUCCESS: Initialized package proj
```
### User Impact
Python users can init a project from the default starter kit instead of
having to supply `--from` or paste a git URL.
### Are there any considerations that need to be addressed for release?
No breaking changes and no `config_version` bump needed —
`NeedsUpdating` already rewrites local configs when the CLI version
changes, so existing users pick the new kit up on their next upgrade.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
[CDTOOL-1707]:
https://fastly.atlassian.net/browse/CDTOOL-1707?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for freeto 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.

3 participants

@posborne@anthony-gomez-fastly@kailan
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

CDTOOL-1649: Add Python Language Support - #1811

Merged
anthony-gomez-fastly merged 14 commits into
mainfrom
posborne/python-language-support
Aug 4, 2026
Merged

CDTOOL-1649: Add Python Language Support#1811
anthony-gomez-fastly merged 14 commits into
mainfrom
posborne/python-language-support

Conversation

@posborne

Copy link
Copy Markdown
Member

This change introduces support for Python on Compute to the fastly CLI. For dependencies, after exploring a few different options it was determined that this responsibility was best left to the fastly-compute-py which executes at a better point in time to correctly determine what is part of a Python services dependency graph (in addition to separation of concerns).

The way this dependency information is passed along, dependent on fastly/compute-sdk-python#89, is that the information is written directly into the WASM component as part of the fastly-compute-py build process. Other information may be injected similarly. This approach may be used by other SDKs/tooling in the future should it make sense or be used directly for "Other" languages.

Discussion is ongoing for the approach we'll follow for Python SDK starter templates but that is not included here as they are not available.

Modify the metadata annotation step to read and preserve any fastly_data
already embedded in the Wasm binary (e.g. by language-specific build tools
like python). This allows build tools to supply package info directly while
the CLI dynamically fills in remaining fields (like cloned repository info).
Add configuration, toolchain parsing, version validation, and build scaffolding
for Python projects inside the compute environment. Host Python >= 3.11 and uv
are utilized as standard toolchain constraints.
Ensure PromptForStarterKit does not index out-of-bounds when there are no
configured starter kits for a language. Instead, prompt the user for a
template git URL directly, or fail gracefully if non-interactive.
@posborne
posborne requested a review from a team as a code ownerJune 3, 2026 19:25
Use 0600 permissions for mock WASM files and add gosec ignore directives for
mock executable creation.
Comment threadCHANGELOG.md Outdated
@anthony-gomez-fastly

Copy link
Copy Markdown
Member

is it worth writing any tests in pkg/commands/compute/build_test.go for python?

Co-authored-by: Anthony Gomez <anthony.gomez@fastly.com>
@posborne

Copy link
Copy Markdown
MemberAuthor

is it worth writing any tests in pkg/commands/compute/build_test.go for python?

Yeah, would definitely be worthwhile I think. I'll work on getting that added.

I also slapped a "DO NOT MERGE YET" label on this for now until the dust settles on our approach for python starter kits and fastly/compute-sdk-python#89. I think this could merge without that PR but I'll want to verify that first.

Introduce TestBuildPython to build_test.go covering:
- Handling missing fastly.toml manifest
- Handling of typical build-time failures
- Dependency checks
- Basic python example
@kpflemingkpfleming changed the title Add Python Language SupportCDTOOL-1649: Add Python Language SupportJun 15, 2026
Comment threadCHANGELOG.md Outdated
Comment threadpkg/commands/compute/init.go Outdated
Comment threadpkg/commands/compute/build.go Outdated
Comment threadpkg/commands/compute/language_python.go Outdated
The entry was under the already-released v15.2.0 section. Also aligns
the PR link formatting with the surrounding entries.
text.Input takes variadic validators, so omitting the argument is the
way to skip validation.
Seeding the whole DataCollection from the binary let a build tool's
script_info, machine_info and build_info override fields the CLI owns.
The CLI now always writes those itself and reads back only the package
list, which is the one thing it cannot collect for Python.
The read is also gated on the language reporting no dependencies of its
own, so the extra `wasm-tools metadata show` subprocess no longer runs
for Rust, Go and JavaScript.
Silently falling back to a hardcoded ">= 3.11" hid a broken or outdated
CLI config and could validate against a constraint we never shipped.
@kailan

Copy link
Copy Markdown
Member

Review feedback is addressed across four commits (3bc678f, c97db52, d360125, d54cbf2). Verified end-to-end by building the CLI and running compute build against a real Python project — the missing-constraint path produces the new error and remediation, and the happy path builds pkg/test.tar.gz with correct merged metadata.

Three things worth flagging before this merges:

1. fastly-compute-py dependency metadata is merged but not released. compute-sdk-python#89 landed on main on 2026-06-05, but the latest tag/release is still v0.1.2 (2026-06-03), and PyPI fastly-compute tops out at 0.1.2. There are 5 unreleased commits on main ahead of that tag.

I confirmed this empirically: running uv run fastly-compute-py build against the pinned fastly-compute==0.1.2 in our testdata produces a producers section containing only language, processed-by and sdk — no fastly_data key. So the package_info read-back path in AnnotateWasmBinaryLong is currently dead code against every released version of the build tool. It's correct, just unexercised until an SDK release goes out.

The good news is the shapes line up: dependencies.rs serialises {"package_info":{"packages":{...}}}, and lib.rs pushes it as a processed-by / fastly_data pair — exactly what readExistingPackageInfo parses. So this should light up on its own once the SDK ships, no CLI change needed. Might be worth cutting that release first so we can validate the merge against a real artifact rather than only the mocked unit test.

2. The embedded pkg/config/config.toml has no [language.python] section. Now that a missing toolchain_constraint is a hard error, a stock config makes every Python build fail. This is the same state cpp is in — scripts/config.sh copies .fastly/config.toml over it at release time — so it should resolve itself through the normal release path. Calling it out because the new error makes the consequence louder than it was for cpp, and it's worth confirming the release script covers it.

3. build_test.go tests for PythonTestBuildPython already exists on the branch (gated behind TEST_COMPUTE_BUILD / TEST_COMPUTE_BUILD_PYTHON), so I believe the earlier question about test coverage is resolved. Flagging in case you wanted something broader than what's there.

@anthony-gomez-fastlyanthony-gomez-fastly left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks you two!

@anthony-gomez-fastly
anthony-gomez-fastly enabled auto-merge (squash) August 4, 2026 15:19
@anthony-gomez-fastly
anthony-gomez-fastly merged commit f975ca4 into mainAug 4, 2026
19 of 23 checks passed
@anthony-gomez-fastly
anthony-gomez-fastly deleted the posborne/python-language-support branch August 4, 2026 15:25
kailan added a commit that referenced this pull request Aug 7, 2026
### Change summary
Fixes [CDTOOL-1707](https://fastly.atlassian.net/browse/CDTOOL-1707).
`fastly compute init --language python` reports that no starter kits
exist:
```
$ fastly compute init --language python --non-interactive
ERROR: no default starter kits configured for this language; please specify a template using the --from flag.
```
Interactively it prints _"No default starter kits are currently
configured for this language"_ and falls back to prompting for a
template git URL.
The starter kits embedded into the CLI binary are injected into
`pkg/config/config.toml` at build time by
[`./scripts/config.sh`](https://github.com/fastly/cli/blob/main/scripts/config.sh),
which holds its own hardcoded list of starter kit repositories. Python
language support (#1811) added `[language.python]` to
`.fastly/config.toml` and wired Python into `NewLanguages()`, but never
added `compute-starter-kit-python-default` to that list — so
`kits.Python` is empty and `PromptForStarterKit` takes its "no kits"
branch. `[language.python]` is present, so `compute build` is
unaffected; the gap is only starter kits.
This adds the repository to the list, plus a test asserting that every
language offered at the `compute init` prompt has at least one starter
kit in the static config, so the same drift is caught for the next
language we add. CI generates the config with `make config` before
running tests, so the test runs against the real generated config.
**Depends on fastly/compute-starter-kit-python-default#6**, which gives
the kit a human-readable `name` in its `fastly.toml`. `config.sh` copies
that field verbatim into the config, so until it merges the prompt
renders `[1] fastly-compute-python-app` rather than `[1] Default starter
for Python`. Nothing needs re-landing here once it merges — the config
is regenerated on each build — but this PR should not be released before
that one.
All Submissions:
* [x] Have you followed the guidelines in our Contributing document?
* [x] Have you checked to ensure there aren't other open [Pull
Requests](https://github.com/fastly/cli/pulls) for the same
update/change?
### Changes to Core Features:
* [x] Have you written new tests for your core changes, as applicable?
* [x] Have you successfully run tests with your changes locally?
Verified end-to-end after `make config`:
```
$ fastly compute init --language python --non-interactive
...
SUCCESS: Initialized package proj
```
### User Impact
Python users can init a project from the default starter kit instead of
having to supply `--from` or paste a git URL.
### Are there any considerations that need to be addressed for release?
No breaking changes and no `config_version` bump needed —
`NeedsUpdating` already rewrites local configs when the CLI version
changes, so existing users pick the new kit up on their next upgrade.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
[CDTOOL-1707]:
https://fastly.atlassian.net/browse/CDTOOL-1707?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for freeto 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.

3 participants

@posborne@anthony-gomez-fastly@kailan
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

CDTOOL-1649: Add Python Language Support - #1811

Merged
anthony-gomez-fastly merged 14 commits into
mainfrom
posborne/python-language-support
Aug 4, 2026
Merged

CDTOOL-1649: Add Python Language Support#1811
anthony-gomez-fastly merged 14 commits into
mainfrom
posborne/python-language-support

Conversation

@posborne

Copy link
Copy Markdown
Member

This change introduces support for Python on Compute to the fastly CLI. For dependencies, after exploring a few different options it was determined that this responsibility was best left to the fastly-compute-py which executes at a better point in time to correctly determine what is part of a Python services dependency graph (in addition to separation of concerns).

The way this dependency information is passed along, dependent on fastly/compute-sdk-python#89, is that the information is written directly into the WASM component as part of the fastly-compute-py build process. Other information may be injected similarly. This approach may be used by other SDKs/tooling in the future should it make sense or be used directly for "Other" languages.

Discussion is ongoing for the approach we'll follow for Python SDK starter templates but that is not included here as they are not available.

Modify the metadata annotation step to read and preserve any fastly_data
already embedded in the Wasm binary (e.g. by language-specific build tools
like python). This allows build tools to supply package info directly while
the CLI dynamically fills in remaining fields (like cloned repository info).
Add configuration, toolchain parsing, version validation, and build scaffolding
for Python projects inside the compute environment. Host Python >= 3.11 and uv
are utilized as standard toolchain constraints.
Ensure PromptForStarterKit does not index out-of-bounds when there are no
configured starter kits for a language. Instead, prompt the user for a
template git URL directly, or fail gracefully if non-interactive.
@posborne
posborne requested a review from a team as a code ownerJune 3, 2026 19:25
Use 0600 permissions for mock WASM files and add gosec ignore directives for
mock executable creation.
Comment threadCHANGELOG.md Outdated
@anthony-gomez-fastly

Copy link
Copy Markdown
Member

is it worth writing any tests in pkg/commands/compute/build_test.go for python?

Co-authored-by: Anthony Gomez <anthony.gomez@fastly.com>
@posborne

Copy link
Copy Markdown
MemberAuthor

is it worth writing any tests in pkg/commands/compute/build_test.go for python?

Yeah, would definitely be worthwhile I think. I'll work on getting that added.

I also slapped a "DO NOT MERGE YET" label on this for now until the dust settles on our approach for python starter kits and fastly/compute-sdk-python#89. I think this could merge without that PR but I'll want to verify that first.

Introduce TestBuildPython to build_test.go covering:
- Handling missing fastly.toml manifest
- Handling of typical build-time failures
- Dependency checks
- Basic python example
@kpflemingkpfleming changed the title Add Python Language SupportCDTOOL-1649: Add Python Language SupportJun 15, 2026
Comment threadCHANGELOG.md Outdated
Comment threadpkg/commands/compute/init.go Outdated
Comment threadpkg/commands/compute/build.go Outdated
Comment threadpkg/commands/compute/language_python.go Outdated
The entry was under the already-released v15.2.0 section. Also aligns
the PR link formatting with the surrounding entries.
text.Input takes variadic validators, so omitting the argument is the
way to skip validation.
Seeding the whole DataCollection from the binary let a build tool's
script_info, machine_info and build_info override fields the CLI owns.
The CLI now always writes those itself and reads back only the package
list, which is the one thing it cannot collect for Python.
The read is also gated on the language reporting no dependencies of its
own, so the extra `wasm-tools metadata show` subprocess no longer runs
for Rust, Go and JavaScript.
Silently falling back to a hardcoded ">= 3.11" hid a broken or outdated
CLI config and could validate against a constraint we never shipped.
@kailan

Copy link
Copy Markdown
Member

Review feedback is addressed across four commits (3bc678f, c97db52, d360125, d54cbf2). Verified end-to-end by building the CLI and running compute build against a real Python project — the missing-constraint path produces the new error and remediation, and the happy path builds pkg/test.tar.gz with correct merged metadata.

Three things worth flagging before this merges:

1. fastly-compute-py dependency metadata is merged but not released. compute-sdk-python#89 landed on main on 2026-06-05, but the latest tag/release is still v0.1.2 (2026-06-03), and PyPI fastly-compute tops out at 0.1.2. There are 5 unreleased commits on main ahead of that tag.

I confirmed this empirically: running uv run fastly-compute-py build against the pinned fastly-compute==0.1.2 in our testdata produces a producers section containing only language, processed-by and sdk — no fastly_data key. So the package_info read-back path in AnnotateWasmBinaryLong is currently dead code against every released version of the build tool. It's correct, just unexercised until an SDK release goes out.

The good news is the shapes line up: dependencies.rs serialises {"package_info":{"packages":{...}}}, and lib.rs pushes it as a processed-by / fastly_data pair — exactly what readExistingPackageInfo parses. So this should light up on its own once the SDK ships, no CLI change needed. Might be worth cutting that release first so we can validate the merge against a real artifact rather than only the mocked unit test.

2. The embedded pkg/config/config.toml has no [language.python] section. Now that a missing toolchain_constraint is a hard error, a stock config makes every Python build fail. This is the same state cpp is in — scripts/config.sh copies .fastly/config.toml over it at release time — so it should resolve itself through the normal release path. Calling it out because the new error makes the consequence louder than it was for cpp, and it's worth confirming the release script covers it.

3. build_test.go tests for PythonTestBuildPython already exists on the branch (gated behind TEST_COMPUTE_BUILD / TEST_COMPUTE_BUILD_PYTHON), so I believe the earlier question about test coverage is resolved. Flagging in case you wanted something broader than what's there.

@anthony-gomez-fastlyanthony-gomez-fastly left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks you two!

@anthony-gomez-fastly
anthony-gomez-fastly enabled auto-merge (squash) August 4, 2026 15:19
@anthony-gomez-fastly
anthony-gomez-fastly merged commit f975ca4 into mainAug 4, 2026
19 of 23 checks passed
@anthony-gomez-fastly
anthony-gomez-fastly deleted the posborne/python-language-support branch August 4, 2026 15:25
kailan added a commit that referenced this pull request Aug 7, 2026
### Change summary
Fixes [CDTOOL-1707](https://fastly.atlassian.net/browse/CDTOOL-1707).
`fastly compute init --language python` reports that no starter kits
exist:
```
$ fastly compute init --language python --non-interactive
ERROR: no default starter kits configured for this language; please specify a template using the --from flag.
```
Interactively it prints _"No default starter kits are currently
configured for this language"_ and falls back to prompting for a
template git URL.
The starter kits embedded into the CLI binary are injected into
`pkg/config/config.toml` at build time by
[`./scripts/config.sh`](https://github.com/fastly/cli/blob/main/scripts/config.sh),
which holds its own hardcoded list of starter kit repositories. Python
language support (#1811) added `[language.python]` to
`.fastly/config.toml` and wired Python into `NewLanguages()`, but never
added `compute-starter-kit-python-default` to that list — so
`kits.Python` is empty and `PromptForStarterKit` takes its "no kits"
branch. `[language.python]` is present, so `compute build` is
unaffected; the gap is only starter kits.
This adds the repository to the list, plus a test asserting that every
language offered at the `compute init` prompt has at least one starter
kit in the static config, so the same drift is caught for the next
language we add. CI generates the config with `make config` before
running tests, so the test runs against the real generated config.
**Depends on fastly/compute-starter-kit-python-default#6**, which gives
the kit a human-readable `name` in its `fastly.toml`. `config.sh` copies
that field verbatim into the config, so until it merges the prompt
renders `[1] fastly-compute-python-app` rather than `[1] Default starter
for Python`. Nothing needs re-landing here once it merges — the config
is regenerated on each build — but this PR should not be released before
that one.
All Submissions:
* [x] Have you followed the guidelines in our Contributing document?
* [x] Have you checked to ensure there aren't other open [Pull
Requests](https://github.com/fastly/cli/pulls) for the same
update/change?
### Changes to Core Features:
* [x] Have you written new tests for your core changes, as applicable?
* [x] Have you successfully run tests with your changes locally?
Verified end-to-end after `make config`:
```
$ fastly compute init --language python --non-interactive
...
SUCCESS: Initialized package proj
```
### User Impact
Python users can init a project from the default starter kit instead of
having to supply `--from` or paste a git URL.
### Are there any considerations that need to be addressed for release?
No breaking changes and no `config_version` bump needed —
`NeedsUpdating` already rewrites local configs when the CLI version
changes, so existing users pick the new kit up on their next upgrade.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
[CDTOOL-1707]:
https://fastly.atlassian.net/browse/CDTOOL-1707?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for freeto 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.

3 participants

@posborne@anthony-gomez-fastly@kailan
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

CDTOOL-1649: Add Python Language Support - #1811

Merged
anthony-gomez-fastly merged 14 commits into
mainfrom
posborne/python-language-support
Aug 4, 2026
Merged

CDTOOL-1649: Add Python Language Support#1811
anthony-gomez-fastly merged 14 commits into
mainfrom
posborne/python-language-support

Conversation

@posborne

Copy link
Copy Markdown
Member

This change introduces support for Python on Compute to the fastly CLI. For dependencies, after exploring a few different options it was determined that this responsibility was best left to the fastly-compute-py which executes at a better point in time to correctly determine what is part of a Python services dependency graph (in addition to separation of concerns).

The way this dependency information is passed along, dependent on fastly/compute-sdk-python#89, is that the information is written directly into the WASM component as part of the fastly-compute-py build process. Other information may be injected similarly. This approach may be used by other SDKs/tooling in the future should it make sense or be used directly for "Other" languages.

Discussion is ongoing for the approach we'll follow for Python SDK starter templates but that is not included here as they are not available.

Modify the metadata annotation step to read and preserve any fastly_data
already embedded in the Wasm binary (e.g. by language-specific build tools
like python). This allows build tools to supply package info directly while
the CLI dynamically fills in remaining fields (like cloned repository info).
Add configuration, toolchain parsing, version validation, and build scaffolding
for Python projects inside the compute environment. Host Python >= 3.11 and uv
are utilized as standard toolchain constraints.
Ensure PromptForStarterKit does not index out-of-bounds when there are no
configured starter kits for a language. Instead, prompt the user for a
template git URL directly, or fail gracefully if non-interactive.
@posborne
posborne requested a review from a team as a code ownerJune 3, 2026 19:25
Use 0600 permissions for mock WASM files and add gosec ignore directives for
mock executable creation.
Comment threadCHANGELOG.md Outdated
@anthony-gomez-fastly

Copy link
Copy Markdown
Member

is it worth writing any tests in pkg/commands/compute/build_test.go for python?

Co-authored-by: Anthony Gomez <anthony.gomez@fastly.com>
@posborne

Copy link
Copy Markdown
MemberAuthor

is it worth writing any tests in pkg/commands/compute/build_test.go for python?

Yeah, would definitely be worthwhile I think. I'll work on getting that added.

I also slapped a "DO NOT MERGE YET" label on this for now until the dust settles on our approach for python starter kits and fastly/compute-sdk-python#89. I think this could merge without that PR but I'll want to verify that first.

Introduce TestBuildPython to build_test.go covering:
- Handling missing fastly.toml manifest
- Handling of typical build-time failures
- Dependency checks
- Basic python example
@kpflemingkpfleming changed the title Add Python Language SupportCDTOOL-1649: Add Python Language SupportJun 15, 2026
Comment threadCHANGELOG.md Outdated
Comment threadpkg/commands/compute/init.go Outdated
Comment threadpkg/commands/compute/build.go Outdated
Comment threadpkg/commands/compute/language_python.go Outdated
The entry was under the already-released v15.2.0 section. Also aligns
the PR link formatting with the surrounding entries.
text.Input takes variadic validators, so omitting the argument is the
way to skip validation.
Seeding the whole DataCollection from the binary let a build tool's
script_info, machine_info and build_info override fields the CLI owns.
The CLI now always writes those itself and reads back only the package
list, which is the one thing it cannot collect for Python.
The read is also gated on the language reporting no dependencies of its
own, so the extra `wasm-tools metadata show` subprocess no longer runs
for Rust, Go and JavaScript.
Silently falling back to a hardcoded ">= 3.11" hid a broken or outdated
CLI config and could validate against a constraint we never shipped.
@kailan

Copy link
Copy Markdown
Member

Review feedback is addressed across four commits (3bc678f, c97db52, d360125, d54cbf2). Verified end-to-end by building the CLI and running compute build against a real Python project — the missing-constraint path produces the new error and remediation, and the happy path builds pkg/test.tar.gz with correct merged metadata.

Three things worth flagging before this merges:

1. fastly-compute-py dependency metadata is merged but not released. compute-sdk-python#89 landed on main on 2026-06-05, but the latest tag/release is still v0.1.2 (2026-06-03), and PyPI fastly-compute tops out at 0.1.2. There are 5 unreleased commits on main ahead of that tag.

I confirmed this empirically: running uv run fastly-compute-py build against the pinned fastly-compute==0.1.2 in our testdata produces a producers section containing only language, processed-by and sdk — no fastly_data key. So the package_info read-back path in AnnotateWasmBinaryLong is currently dead code against every released version of the build tool. It's correct, just unexercised until an SDK release goes out.

The good news is the shapes line up: dependencies.rs serialises {"package_info":{"packages":{...}}}, and lib.rs pushes it as a processed-by / fastly_data pair — exactly what readExistingPackageInfo parses. So this should light up on its own once the SDK ships, no CLI change needed. Might be worth cutting that release first so we can validate the merge against a real artifact rather than only the mocked unit test.

2. The embedded pkg/config/config.toml has no [language.python] section. Now that a missing toolchain_constraint is a hard error, a stock config makes every Python build fail. This is the same state cpp is in — scripts/config.sh copies .fastly/config.toml over it at release time — so it should resolve itself through the normal release path. Calling it out because the new error makes the consequence louder than it was for cpp, and it's worth confirming the release script covers it.

3. build_test.go tests for PythonTestBuildPython already exists on the branch (gated behind TEST_COMPUTE_BUILD / TEST_COMPUTE_BUILD_PYTHON), so I believe the earlier question about test coverage is resolved. Flagging in case you wanted something broader than what's there.

@anthony-gomez-fastlyanthony-gomez-fastly left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks you two!

@anthony-gomez-fastly
anthony-gomez-fastly enabled auto-merge (squash) August 4, 2026 15:19
@anthony-gomez-fastly
anthony-gomez-fastly merged commit f975ca4 into mainAug 4, 2026
19 of 23 checks passed
@anthony-gomez-fastly
anthony-gomez-fastly deleted the posborne/python-language-support branch August 4, 2026 15:25
kailan added a commit that referenced this pull request Aug 7, 2026
### Change summary
Fixes [CDTOOL-1707](https://fastly.atlassian.net/browse/CDTOOL-1707).
`fastly compute init --language python` reports that no starter kits
exist:
```
$ fastly compute init --language python --non-interactive
ERROR: no default starter kits configured for this language; please specify a template using the --from flag.
```
Interactively it prints _"No default starter kits are currently
configured for this language"_ and falls back to prompting for a
template git URL.
The starter kits embedded into the CLI binary are injected into
`pkg/config/config.toml` at build time by
[`./scripts/config.sh`](https://github.com/fastly/cli/blob/main/scripts/config.sh),
which holds its own hardcoded list of starter kit repositories. Python
language support (#1811) added `[language.python]` to
`.fastly/config.toml` and wired Python into `NewLanguages()`, but never
added `compute-starter-kit-python-default` to that list — so
`kits.Python` is empty and `PromptForStarterKit` takes its "no kits"
branch. `[language.python]` is present, so `compute build` is
unaffected; the gap is only starter kits.
This adds the repository to the list, plus a test asserting that every
language offered at the `compute init` prompt has at least one starter
kit in the static config, so the same drift is caught for the next
language we add. CI generates the config with `make config` before
running tests, so the test runs against the real generated config.
**Depends on fastly/compute-starter-kit-python-default#6**, which gives
the kit a human-readable `name` in its `fastly.toml`. `config.sh` copies
that field verbatim into the config, so until it merges the prompt
renders `[1] fastly-compute-python-app` rather than `[1] Default starter
for Python`. Nothing needs re-landing here once it merges — the config
is regenerated on each build — but this PR should not be released before
that one.
All Submissions:
* [x] Have you followed the guidelines in our Contributing document?
* [x] Have you checked to ensure there aren't other open [Pull
Requests](https://github.com/fastly/cli/pulls) for the same
update/change?
### Changes to Core Features:
* [x] Have you written new tests for your core changes, as applicable?
* [x] Have you successfully run tests with your changes locally?
Verified end-to-end after `make config`:
```
$ fastly compute init --language python --non-interactive
...
SUCCESS: Initialized package proj
```
### User Impact
Python users can init a project from the default starter kit instead of
having to supply `--from` or paste a git URL.
### Are there any considerations that need to be addressed for release?
No breaking changes and no `config_version` bump needed —
`NeedsUpdating` already rewrites local configs when the CLI version
changes, so existing users pick the new kit up on their next upgrade.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
[CDTOOL-1707]:
https://fastly.atlassian.net/browse/CDTOOL-1707?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for freeto 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.

3 participants

@posborne@anthony-gomez-fastly@kailan
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

CDTOOL-1649: Add Python Language Support - #1811

Merged
anthony-gomez-fastly merged 14 commits into
mainfrom
posborne/python-language-support
Aug 4, 2026
Merged

CDTOOL-1649: Add Python Language Support#1811
anthony-gomez-fastly merged 14 commits into
mainfrom
posborne/python-language-support

Conversation

@posborne

Copy link
Copy Markdown
Member

This change introduces support for Python on Compute to the fastly CLI. For dependencies, after exploring a few different options it was determined that this responsibility was best left to the fastly-compute-py which executes at a better point in time to correctly determine what is part of a Python services dependency graph (in addition to separation of concerns).

The way this dependency information is passed along, dependent on fastly/compute-sdk-python#89, is that the information is written directly into the WASM component as part of the fastly-compute-py build process. Other information may be injected similarly. This approach may be used by other SDKs/tooling in the future should it make sense or be used directly for "Other" languages.

Discussion is ongoing for the approach we'll follow for Python SDK starter templates but that is not included here as they are not available.

Modify the metadata annotation step to read and preserve any fastly_data
already embedded in the Wasm binary (e.g. by language-specific build tools
like python). This allows build tools to supply package info directly while
the CLI dynamically fills in remaining fields (like cloned repository info).
Add configuration, toolchain parsing, version validation, and build scaffolding
for Python projects inside the compute environment. Host Python >= 3.11 and uv
are utilized as standard toolchain constraints.
Ensure PromptForStarterKit does not index out-of-bounds when there are no
configured starter kits for a language. Instead, prompt the user for a
template git URL directly, or fail gracefully if non-interactive.
@posborne
posborne requested a review from a team as a code ownerJune 3, 2026 19:25
Use 0600 permissions for mock WASM files and add gosec ignore directives for
mock executable creation.
Comment threadCHANGELOG.md Outdated
@anthony-gomez-fastly

Copy link
Copy Markdown
Member

is it worth writing any tests in pkg/commands/compute/build_test.go for python?

Co-authored-by: Anthony Gomez <anthony.gomez@fastly.com>
@posborne

Copy link
Copy Markdown
MemberAuthor

is it worth writing any tests in pkg/commands/compute/build_test.go for python?

Yeah, would definitely be worthwhile I think. I'll work on getting that added.

I also slapped a "DO NOT MERGE YET" label on this for now until the dust settles on our approach for python starter kits and fastly/compute-sdk-python#89. I think this could merge without that PR but I'll want to verify that first.

Introduce TestBuildPython to build_test.go covering:
- Handling missing fastly.toml manifest
- Handling of typical build-time failures
- Dependency checks
- Basic python example
@kpflemingkpfleming changed the title Add Python Language SupportCDTOOL-1649: Add Python Language SupportJun 15, 2026
Comment threadCHANGELOG.md Outdated
Comment threadpkg/commands/compute/init.go Outdated
Comment threadpkg/commands/compute/build.go Outdated
Comment threadpkg/commands/compute/language_python.go Outdated
The entry was under the already-released v15.2.0 section. Also aligns
the PR link formatting with the surrounding entries.
text.Input takes variadic validators, so omitting the argument is the
way to skip validation.
Seeding the whole DataCollection from the binary let a build tool's
script_info, machine_info and build_info override fields the CLI owns.
The CLI now always writes those itself and reads back only the package
list, which is the one thing it cannot collect for Python.
The read is also gated on the language reporting no dependencies of its
own, so the extra `wasm-tools metadata show` subprocess no longer runs
for Rust, Go and JavaScript.
Silently falling back to a hardcoded ">= 3.11" hid a broken or outdated
CLI config and could validate against a constraint we never shipped.
@kailan

Copy link
Copy Markdown
Member

Review feedback is addressed across four commits (3bc678f, c97db52, d360125, d54cbf2). Verified end-to-end by building the CLI and running compute build against a real Python project — the missing-constraint path produces the new error and remediation, and the happy path builds pkg/test.tar.gz with correct merged metadata.

Three things worth flagging before this merges:

1. fastly-compute-py dependency metadata is merged but not released. compute-sdk-python#89 landed on main on 2026-06-05, but the latest tag/release is still v0.1.2 (2026-06-03), and PyPI fastly-compute tops out at 0.1.2. There are 5 unreleased commits on main ahead of that tag.

I confirmed this empirically: running uv run fastly-compute-py build against the pinned fastly-compute==0.1.2 in our testdata produces a producers section containing only language, processed-by and sdk — no fastly_data key. So the package_info read-back path in AnnotateWasmBinaryLong is currently dead code against every released version of the build tool. It's correct, just unexercised until an SDK release goes out.

The good news is the shapes line up: dependencies.rs serialises {"package_info":{"packages":{...}}}, and lib.rs pushes it as a processed-by / fastly_data pair — exactly what readExistingPackageInfo parses. So this should light up on its own once the SDK ships, no CLI change needed. Might be worth cutting that release first so we can validate the merge against a real artifact rather than only the mocked unit test.

2. The embedded pkg/config/config.toml has no [language.python] section. Now that a missing toolchain_constraint is a hard error, a stock config makes every Python build fail. This is the same state cpp is in — scripts/config.sh copies .fastly/config.toml over it at release time — so it should resolve itself through the normal release path. Calling it out because the new error makes the consequence louder than it was for cpp, and it's worth confirming the release script covers it.

3. build_test.go tests for PythonTestBuildPython already exists on the branch (gated behind TEST_COMPUTE_BUILD / TEST_COMPUTE_BUILD_PYTHON), so I believe the earlier question about test coverage is resolved. Flagging in case you wanted something broader than what's there.

@anthony-gomez-fastlyanthony-gomez-fastly left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks you two!

@anthony-gomez-fastly
anthony-gomez-fastly enabled auto-merge (squash) August 4, 2026 15:19
@anthony-gomez-fastly
anthony-gomez-fastly merged commit f975ca4 into mainAug 4, 2026
19 of 23 checks passed
@anthony-gomez-fastly
anthony-gomez-fastly deleted the posborne/python-language-support branch August 4, 2026 15:25
kailan added a commit that referenced this pull request Aug 7, 2026
### Change summary
Fixes [CDTOOL-1707](https://fastly.atlassian.net/browse/CDTOOL-1707).
`fastly compute init --language python` reports that no starter kits
exist:
```
$ fastly compute init --language python --non-interactive
ERROR: no default starter kits configured for this language; please specify a template using the --from flag.
```
Interactively it prints _"No default starter kits are currently
configured for this language"_ and falls back to prompting for a
template git URL.
The starter kits embedded into the CLI binary are injected into
`pkg/config/config.toml` at build time by
[`./scripts/config.sh`](https://github.com/fastly/cli/blob/main/scripts/config.sh),
which holds its own hardcoded list of starter kit repositories. Python
language support (#1811) added `[language.python]` to
`.fastly/config.toml` and wired Python into `NewLanguages()`, but never
added `compute-starter-kit-python-default` to that list — so
`kits.Python` is empty and `PromptForStarterKit` takes its "no kits"
branch. `[language.python]` is present, so `compute build` is
unaffected; the gap is only starter kits.
This adds the repository to the list, plus a test asserting that every
language offered at the `compute init` prompt has at least one starter
kit in the static config, so the same drift is caught for the next
language we add. CI generates the config with `make config` before
running tests, so the test runs against the real generated config.
**Depends on fastly/compute-starter-kit-python-default#6**, which gives
the kit a human-readable `name` in its `fastly.toml`. `config.sh` copies
that field verbatim into the config, so until it merges the prompt
renders `[1] fastly-compute-python-app` rather than `[1] Default starter
for Python`. Nothing needs re-landing here once it merges — the config
is regenerated on each build — but this PR should not be released before
that one.
All Submissions:
* [x] Have you followed the guidelines in our Contributing document?
* [x] Have you checked to ensure there aren't other open [Pull
Requests](https://github.com/fastly/cli/pulls) for the same
update/change?
### Changes to Core Features:
* [x] Have you written new tests for your core changes, as applicable?
* [x] Have you successfully run tests with your changes locally?
Verified end-to-end after `make config`:
```
$ fastly compute init --language python --non-interactive
...
SUCCESS: Initialized package proj
```
### User Impact
Python users can init a project from the default starter kit instead of
having to supply `--from` or paste a git URL.
### Are there any considerations that need to be addressed for release?
No breaking changes and no `config_version` bump needed —
`NeedsUpdating` already rewrites local configs when the CLI version
changes, so existing users pick the new kit up on their next upgrade.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
[CDTOOL-1707]:
https://fastly.atlassian.net/browse/CDTOOL-1707?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for freeto 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.

3 participants

@posborne@anthony-gomez-fastly@kailan
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

CDTOOL-1649: Add Python Language Support - #1811

Merged
anthony-gomez-fastly merged 14 commits into
mainfrom
posborne/python-language-support
Aug 4, 2026
Merged

CDTOOL-1649: Add Python Language Support#1811
anthony-gomez-fastly merged 14 commits into
mainfrom
posborne/python-language-support

Conversation

@posborne

Copy link
Copy Markdown
Member

This change introduces support for Python on Compute to the fastly CLI. For dependencies, after exploring a few different options it was determined that this responsibility was best left to the fastly-compute-py which executes at a better point in time to correctly determine what is part of a Python services dependency graph (in addition to separation of concerns).

The way this dependency information is passed along, dependent on fastly/compute-sdk-python#89, is that the information is written directly into the WASM component as part of the fastly-compute-py build process. Other information may be injected similarly. This approach may be used by other SDKs/tooling in the future should it make sense or be used directly for "Other" languages.

Discussion is ongoing for the approach we'll follow for Python SDK starter templates but that is not included here as they are not available.

Modify the metadata annotation step to read and preserve any fastly_data
already embedded in the Wasm binary (e.g. by language-specific build tools
like python). This allows build tools to supply package info directly while
the CLI dynamically fills in remaining fields (like cloned repository info).
Add configuration, toolchain parsing, version validation, and build scaffolding
for Python projects inside the compute environment. Host Python >= 3.11 and uv
are utilized as standard toolchain constraints.
Ensure PromptForStarterKit does not index out-of-bounds when there are no
configured starter kits for a language. Instead, prompt the user for a
template git URL directly, or fail gracefully if non-interactive.
@posborne
posborne requested a review from a team as a code ownerJune 3, 2026 19:25
Use 0600 permissions for mock WASM files and add gosec ignore directives for
mock executable creation.
Comment threadCHANGELOG.md Outdated
@anthony-gomez-fastly

Copy link
Copy Markdown
Member

is it worth writing any tests in pkg/commands/compute/build_test.go for python?

Co-authored-by: Anthony Gomez <anthony.gomez@fastly.com>
@posborne

Copy link
Copy Markdown
MemberAuthor

is it worth writing any tests in pkg/commands/compute/build_test.go for python?

Yeah, would definitely be worthwhile I think. I'll work on getting that added.

I also slapped a "DO NOT MERGE YET" label on this for now until the dust settles on our approach for python starter kits and fastly/compute-sdk-python#89. I think this could merge without that PR but I'll want to verify that first.

Introduce TestBuildPython to build_test.go covering:
- Handling missing fastly.toml manifest
- Handling of typical build-time failures
- Dependency checks
- Basic python example
@kpflemingkpfleming changed the title Add Python Language SupportCDTOOL-1649: Add Python Language SupportJun 15, 2026
Comment threadCHANGELOG.md Outdated
Comment threadpkg/commands/compute/init.go Outdated
Comment threadpkg/commands/compute/build.go Outdated
Comment threadpkg/commands/compute/language_python.go Outdated
The entry was under the already-released v15.2.0 section. Also aligns
the PR link formatting with the surrounding entries.
text.Input takes variadic validators, so omitting the argument is the
way to skip validation.
Seeding the whole DataCollection from the binary let a build tool's
script_info, machine_info and build_info override fields the CLI owns.
The CLI now always writes those itself and reads back only the package
list, which is the one thing it cannot collect for Python.
The read is also gated on the language reporting no dependencies of its
own, so the extra `wasm-tools metadata show` subprocess no longer runs
for Rust, Go and JavaScript.
Silently falling back to a hardcoded ">= 3.11" hid a broken or outdated
CLI config and could validate against a constraint we never shipped.
@kailan

Copy link
Copy Markdown
Member

Review feedback is addressed across four commits (3bc678f, c97db52, d360125, d54cbf2). Verified end-to-end by building the CLI and running compute build against a real Python project — the missing-constraint path produces the new error and remediation, and the happy path builds pkg/test.tar.gz with correct merged metadata.

Three things worth flagging before this merges:

1. fastly-compute-py dependency metadata is merged but not released. compute-sdk-python#89 landed on main on 2026-06-05, but the latest tag/release is still v0.1.2 (2026-06-03), and PyPI fastly-compute tops out at 0.1.2. There are 5 unreleased commits on main ahead of that tag.

I confirmed this empirically: running uv run fastly-compute-py build against the pinned fastly-compute==0.1.2 in our testdata produces a producers section containing only language, processed-by and sdk — no fastly_data key. So the package_info read-back path in AnnotateWasmBinaryLong is currently dead code against every released version of the build tool. It's correct, just unexercised until an SDK release goes out.

The good news is the shapes line up: dependencies.rs serialises {"package_info":{"packages":{...}}}, and lib.rs pushes it as a processed-by / fastly_data pair — exactly what readExistingPackageInfo parses. So this should light up on its own once the SDK ships, no CLI change needed. Might be worth cutting that release first so we can validate the merge against a real artifact rather than only the mocked unit test.

2. The embedded pkg/config/config.toml has no [language.python] section. Now that a missing toolchain_constraint is a hard error, a stock config makes every Python build fail. This is the same state cpp is in — scripts/config.sh copies .fastly/config.toml over it at release time — so it should resolve itself through the normal release path. Calling it out because the new error makes the consequence louder than it was for cpp, and it's worth confirming the release script covers it.

3. build_test.go tests for PythonTestBuildPython already exists on the branch (gated behind TEST_COMPUTE_BUILD / TEST_COMPUTE_BUILD_PYTHON), so I believe the earlier question about test coverage is resolved. Flagging in case you wanted something broader than what's there.

@anthony-gomez-fastlyanthony-gomez-fastly left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks you two!

@anthony-gomez-fastly
anthony-gomez-fastly enabled auto-merge (squash) August 4, 2026 15:19
@anthony-gomez-fastly
anthony-gomez-fastly merged commit f975ca4 into mainAug 4, 2026
19 of 23 checks passed
@anthony-gomez-fastly
anthony-gomez-fastly deleted the posborne/python-language-support branch August 4, 2026 15:25
kailan added a commit that referenced this pull request Aug 7, 2026
### Change summary
Fixes [CDTOOL-1707](https://fastly.atlassian.net/browse/CDTOOL-1707).
`fastly compute init --language python` reports that no starter kits
exist:
```
$ fastly compute init --language python --non-interactive
ERROR: no default starter kits configured for this language; please specify a template using the --from flag.
```
Interactively it prints _"No default starter kits are currently
configured for this language"_ and falls back to prompting for a
template git URL.
The starter kits embedded into the CLI binary are injected into
`pkg/config/config.toml` at build time by
[`./scripts/config.sh`](https://github.com/fastly/cli/blob/main/scripts/config.sh),
which holds its own hardcoded list of starter kit repositories. Python
language support (#1811) added `[language.python]` to
`.fastly/config.toml` and wired Python into `NewLanguages()`, but never
added `compute-starter-kit-python-default` to that list — so
`kits.Python` is empty and `PromptForStarterKit` takes its "no kits"
branch. `[language.python]` is present, so `compute build` is
unaffected; the gap is only starter kits.
This adds the repository to the list, plus a test asserting that every
language offered at the `compute init` prompt has at least one starter
kit in the static config, so the same drift is caught for the next
language we add. CI generates the config with `make config` before
running tests, so the test runs against the real generated config.
**Depends on fastly/compute-starter-kit-python-default#6**, which gives
the kit a human-readable `name` in its `fastly.toml`. `config.sh` copies
that field verbatim into the config, so until it merges the prompt
renders `[1] fastly-compute-python-app` rather than `[1] Default starter
for Python`. Nothing needs re-landing here once it merges — the config
is regenerated on each build — but this PR should not be released before
that one.
All Submissions:
* [x] Have you followed the guidelines in our Contributing document?
* [x] Have you checked to ensure there aren't other open [Pull
Requests](https://github.com/fastly/cli/pulls) for the same
update/change?
### Changes to Core Features:
* [x] Have you written new tests for your core changes, as applicable?
* [x] Have you successfully run tests with your changes locally?
Verified end-to-end after `make config`:
```
$ fastly compute init --language python --non-interactive
...
SUCCESS: Initialized package proj
```
### User Impact
Python users can init a project from the default starter kit instead of
having to supply `--from` or paste a git URL.
### Are there any considerations that need to be addressed for release?
No breaking changes and no `config_version` bump needed —
`NeedsUpdating` already rewrites local configs when the CLI version
changes, so existing users pick the new kit up on their next upgrade.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
[CDTOOL-1707]:
https://fastly.atlassian.net/browse/CDTOOL-1707?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for freeto 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.

3 participants

@posborne@anthony-gomez-fastly@kailan
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

CDTOOL-1649: Add Python Language Support - #1811

Merged
anthony-gomez-fastly merged 14 commits into
mainfrom
posborne/python-language-support
Aug 4, 2026
Merged

CDTOOL-1649: Add Python Language Support#1811
anthony-gomez-fastly merged 14 commits into
mainfrom
posborne/python-language-support

Conversation

@posborne

Copy link
Copy Markdown
Member

This change introduces support for Python on Compute to the fastly CLI. For dependencies, after exploring a few different options it was determined that this responsibility was best left to the fastly-compute-py which executes at a better point in time to correctly determine what is part of a Python services dependency graph (in addition to separation of concerns).

The way this dependency information is passed along, dependent on fastly/compute-sdk-python#89, is that the information is written directly into the WASM component as part of the fastly-compute-py build process. Other information may be injected similarly. This approach may be used by other SDKs/tooling in the future should it make sense or be used directly for "Other" languages.

Discussion is ongoing for the approach we'll follow for Python SDK starter templates but that is not included here as they are not available.

Modify the metadata annotation step to read and preserve any fastly_data
already embedded in the Wasm binary (e.g. by language-specific build tools
like python). This allows build tools to supply package info directly while
the CLI dynamically fills in remaining fields (like cloned repository info).
Add configuration, toolchain parsing, version validation, and build scaffolding
for Python projects inside the compute environment. Host Python >= 3.11 and uv
are utilized as standard toolchain constraints.
Ensure PromptForStarterKit does not index out-of-bounds when there are no
configured starter kits for a language. Instead, prompt the user for a
template git URL directly, or fail gracefully if non-interactive.
@posborne
posborne requested a review from a team as a code ownerJune 3, 2026 19:25
Use 0600 permissions for mock WASM files and add gosec ignore directives for
mock executable creation.
Comment threadCHANGELOG.md Outdated
@anthony-gomez-fastly

Copy link
Copy Markdown
Member

is it worth writing any tests in pkg/commands/compute/build_test.go for python?

Co-authored-by: Anthony Gomez <anthony.gomez@fastly.com>
@posborne

Copy link
Copy Markdown
MemberAuthor

is it worth writing any tests in pkg/commands/compute/build_test.go for python?

Yeah, would definitely be worthwhile I think. I'll work on getting that added.

I also slapped a "DO NOT MERGE YET" label on this for now until the dust settles on our approach for python starter kits and fastly/compute-sdk-python#89. I think this could merge without that PR but I'll want to verify that first.

Introduce TestBuildPython to build_test.go covering:
- Handling missing fastly.toml manifest
- Handling of typical build-time failures
- Dependency checks
- Basic python example
@kpflemingkpfleming changed the title Add Python Language SupportCDTOOL-1649: Add Python Language SupportJun 15, 2026
Comment threadCHANGELOG.md Outdated
Comment threadpkg/commands/compute/init.go Outdated
Comment threadpkg/commands/compute/build.go Outdated
Comment threadpkg/commands/compute/language_python.go Outdated
The entry was under the already-released v15.2.0 section. Also aligns
the PR link formatting with the surrounding entries.
text.Input takes variadic validators, so omitting the argument is the
way to skip validation.
Seeding the whole DataCollection from the binary let a build tool's
script_info, machine_info and build_info override fields the CLI owns.
The CLI now always writes those itself and reads back only the package
list, which is the one thing it cannot collect for Python.
The read is also gated on the language reporting no dependencies of its
own, so the extra `wasm-tools metadata show` subprocess no longer runs
for Rust, Go and JavaScript.
Silently falling back to a hardcoded ">= 3.11" hid a broken or outdated
CLI config and could validate against a constraint we never shipped.
@kailan

Copy link
Copy Markdown
Member

Review feedback is addressed across four commits (3bc678f, c97db52, d360125, d54cbf2). Verified end-to-end by building the CLI and running compute build against a real Python project — the missing-constraint path produces the new error and remediation, and the happy path builds pkg/test.tar.gz with correct merged metadata.

Three things worth flagging before this merges:

1. fastly-compute-py dependency metadata is merged but not released. compute-sdk-python#89 landed on main on 2026-06-05, but the latest tag/release is still v0.1.2 (2026-06-03), and PyPI fastly-compute tops out at 0.1.2. There are 5 unreleased commits on main ahead of that tag.

I confirmed this empirically: running uv run fastly-compute-py build against the pinned fastly-compute==0.1.2 in our testdata produces a producers section containing only language, processed-by and sdk — no fastly_data key. So the package_info read-back path in AnnotateWasmBinaryLong is currently dead code against every released version of the build tool. It's correct, just unexercised until an SDK release goes out.

The good news is the shapes line up: dependencies.rs serialises {"package_info":{"packages":{...}}}, and lib.rs pushes it as a processed-by / fastly_data pair — exactly what readExistingPackageInfo parses. So this should light up on its own once the SDK ships, no CLI change needed. Might be worth cutting that release first so we can validate the merge against a real artifact rather than only the mocked unit test.

2. The embedded pkg/config/config.toml has no [language.python] section. Now that a missing toolchain_constraint is a hard error, a stock config makes every Python build fail. This is the same state cpp is in — scripts/config.sh copies .fastly/config.toml over it at release time — so it should resolve itself through the normal release path. Calling it out because the new error makes the consequence louder than it was for cpp, and it's worth confirming the release script covers it.

3. build_test.go tests for PythonTestBuildPython already exists on the branch (gated behind TEST_COMPUTE_BUILD / TEST_COMPUTE_BUILD_PYTHON), so I believe the earlier question about test coverage is resolved. Flagging in case you wanted something broader than what's there.

@anthony-gomez-fastlyanthony-gomez-fastly left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks you two!

@anthony-gomez-fastly
anthony-gomez-fastly enabled auto-merge (squash) August 4, 2026 15:19
@anthony-gomez-fastly
anthony-gomez-fastly merged commit f975ca4 into mainAug 4, 2026
19 of 23 checks passed
@anthony-gomez-fastly
anthony-gomez-fastly deleted the posborne/python-language-support branch August 4, 2026 15:25
kailan added a commit that referenced this pull request Aug 7, 2026
### Change summary
Fixes [CDTOOL-1707](https://fastly.atlassian.net/browse/CDTOOL-1707).
`fastly compute init --language python` reports that no starter kits
exist:
```
$ fastly compute init --language python --non-interactive
ERROR: no default starter kits configured for this language; please specify a template using the --from flag.
```
Interactively it prints _"No default starter kits are currently
configured for this language"_ and falls back to prompting for a
template git URL.
The starter kits embedded into the CLI binary are injected into
`pkg/config/config.toml` at build time by
[`./scripts/config.sh`](https://github.com/fastly/cli/blob/main/scripts/config.sh),
which holds its own hardcoded list of starter kit repositories. Python
language support (#1811) added `[language.python]` to
`.fastly/config.toml` and wired Python into `NewLanguages()`, but never
added `compute-starter-kit-python-default` to that list — so
`kits.Python` is empty and `PromptForStarterKit` takes its "no kits"
branch. `[language.python]` is present, so `compute build` is
unaffected; the gap is only starter kits.
This adds the repository to the list, plus a test asserting that every
language offered at the `compute init` prompt has at least one starter
kit in the static config, so the same drift is caught for the next
language we add. CI generates the config with `make config` before
running tests, so the test runs against the real generated config.
**Depends on fastly/compute-starter-kit-python-default#6**, which gives
the kit a human-readable `name` in its `fastly.toml`. `config.sh` copies
that field verbatim into the config, so until it merges the prompt
renders `[1] fastly-compute-python-app` rather than `[1] Default starter
for Python`. Nothing needs re-landing here once it merges — the config
is regenerated on each build — but this PR should not be released before
that one.
All Submissions:
* [x] Have you followed the guidelines in our Contributing document?
* [x] Have you checked to ensure there aren't other open [Pull
Requests](https://github.com/fastly/cli/pulls) for the same
update/change?
### Changes to Core Features:
* [x] Have you written new tests for your core changes, as applicable?
* [x] Have you successfully run tests with your changes locally?
Verified end-to-end after `make config`:
```
$ fastly compute init --language python --non-interactive
...
SUCCESS: Initialized package proj
```
### User Impact
Python users can init a project from the default starter kit instead of
having to supply `--from` or paste a git URL.
### Are there any considerations that need to be addressed for release?
No breaking changes and no `config_version` bump needed —
`NeedsUpdating` already rewrites local configs when the CLI version
changes, so existing users pick the new kit up on their next upgrade.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
[CDTOOL-1707]:
https://fastly.atlassian.net/browse/CDTOOL-1707?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for freeto 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.

3 participants

@posborne@anthony-gomez-fastly@kailan