Python: switch from bundled CLI wheels to downloading explicitly or at runtime#1744
Python: switch from bundled CLI wheels to downloading explicitly or at runtime#1744SteveSandersonMS wants to merge 1 commit into
Conversation
7830a9e to
e835f13
Compare
There was a problem hiding this comment.
Pull request overview
This pull request changes the Python SDK packaging model from shipping large platform-specific wheels with a bundled Copilot CLI to shipping a slim pure-Python wheel that downloads and caches the Copilot runtime from GitHub Releases (with checksum verification).
Changes:
- Added Python runtime download + caching implementation (including a
python -m copilot download-runtimeentry point). - Updated Python client CLI resolution to prefer explicit path/env var, then fall back to a downloaded cached runtime.
- Updated publishing workflow and documentation to reflect the new distribution model, and removed the old fat-wheel builder.
Show a summary per file
| File | Description |
|---|---|
| python/scripts/inject-cli-version.mjs | New publish-time script to inject pinned CLI version into Python package. |
| python/scripts/build-wheels.mjs | Removes prior platform wheel builder that bundled runtime binaries. |
| python/README.md | Documents runtime download command, cache paths, and env vars. |
| python/pyproject.toml | Removes bundled-wheel related comments and updates publish-time notes. |
| python/copilot/client.py | Switches CLI resolution fallback from bundled binary to downloaded cached runtime. |
| python/copilot/_cli_version.py | Introduces CLI version sentinel and platform asset mapping for downloads. |
| python/copilot/_cli_download.py | Implements runtime download, SHA256 verification, extraction, and atomic caching. |
| python/copilot/main.py | Adds python -m copilot entry point that routes to download utility. |
| python/.gitignore | Removes ignore for bundled runtime path that no longer exists in-repo. |
| docs/setup/local-cli.md | Updates wording to reflect Python no longer bundles the CLI. |
| docs/setup/bundled-cli.md | Updates default setup docs to describe Python runtime download workflow. |
| docs/getting-started.md | Updates “bundled CLI” wording to “provided automatically”. |
| .github/workflows/publish.yml | Updates Python publish job to inject CLI version and build a single wheel. |
Copilot's findings
- Files reviewed: 13/13 changed files
- Comments generated: 5
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Generated by SDK Consistency Review Agent for issue #1744 · sonnet46 1.4M
e835f13 to
1d5706a
Compare
SteveSandersonMS
left a comment
There was a problem hiding this comment.
All review comments addressed:
- Unsupported platform crash (comments on lines 96, 325): Fixed — both \get_cached_cli_path()\ and \get_or_download_cli()\ now catch RuntimeError from \get_asset_info()\ and return None on unsupported platforms.
- Unit tests (line 220): Agreed, will add in a follow-up commit (mocking urlopen for cache hit, checksum mismatch, skip env var, unsupported platform).
- Misleading pyproject.toml comment (line 16): Fixed — removed the stale comment.
- 'requires' vs 'recommends' in docs (bundled-cli.md line 6): Fixed — changed to 'recommends' since auto-download works as a fallback.
- COPILOT_CLI_CACHE_DIR vs Rust COPILOT_CLI_EXTRACT_DIR (line 12): Intentional difference in semantics (Python appends version subdir, Rust is flat). Updated README to clarify. Aligning names would be a cross-SDK change best done separately.
|
Thanks for the consistency review. The COPILOT_CLI_CACHE_DIR vs COPILOT_CLI_EXTRACT_DIR naming difference is intentional — Python appends \cli//\ under the override (matching the default layout), while Rust's var is a flat directory. Added clarification to the README table. Aligning across SDKs would be a separate cross-SDK change. |
This comment has been minimized.
This comment has been minimized.
Replace the platform-specific fat wheel approach (6 × ~90MB wheels per release)
with a single slim pure-Python wheel that downloads the CLI binary from GitHub
Releases on first use and caches it locally.
Key changes:
- New _cli_version.py: platform asset mapping, version sentinel (injected at
publish time by inject-cli-version.mjs)
- New _cli_download.py: download, SHA-256 verify, extract, atomic cache logic
- New __main__.py: 'python -m copilot download-cli' pre-download command
- Updated client.py resolution chain: explicit > env var > downloaded (removed
bundled binary fallback entirely)
- Updated publish.yml: single 'uv build --wheel' instead of build-wheels.mjs
- Removed build-wheels.mjs (old fat wheel builder)
- Updated docs to reflect Python's new download model
The cache directory is shared with the Rust SDK:
Linux: ~/.cache/github-copilot-sdk/cli/{version}/copilot
macOS: ~/Library/Caches/github-copilot-sdk/cli/{version}/copilot
Windows: %LOCALAPPDATA%\github-copilot-sdk\cli\{version}\copilot.exe
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1d5706a to
75d4a8b
Compare
Cross-SDK Consistency Review ✅This PR changes only the Python SDK's CLI distribution mechanism (fat wheels → slim wheel + runtime download) and its associated docs/CI. No cross-SDK consistency issues found. Key consistency checks:
No changes needed in other SDKs. Node.js, Go, .NET, Java, and Rust each use their own appropriate CLI delivery mechanism; this PR doesn't introduce a new public feature that needs to be mirrored — it's a packaging-level change internal to Python's distribution model.
|
Summary
Replace the platform-specific fat wheel approach (6 x ~90MB wheels per release) with a single slim pure-Python wheel (~100KB) that downloads the Copilot runtime from GitHub Releases.
How it works
CLI_VERSIONinjected at build timepython -m copilot download-runtimeto fetch the runtimeSHA256SUMS.txtfrom the same releaseWheel output
Before: 6 platform wheels (
manylinux_x86_64,macosx_arm64, etc.) ~540MB totalAfter: 1 universal wheel
github_copilot_sdk-{version}-py3-none-any.whl~100KBChanges
New files:
python/copilot/_cli_version.py- version sentinel + platform asset mappingpython/copilot/_cli_download.py- download, SHA-256 verify, extract, atomic cachepython/copilot/__main__.py-python -m copilot download-clientry pointpython/scripts/inject-cli-version.mjs- publish-time version injectorModified:
python/copilot/client.py- resolution chain uses download fallback (bundled path removed)python/pyproject.toml- removed fat-wheel comments.github/workflows/publish.yml- singleuv build --wheel+ inject scriptDeleted:
python/scripts/build-wheels.mjs(old platform wheel builder)