Skip to content

feat(python-sdk): pure-Python bootstrap on PyPI fetches native wheels from GH Releases#45

Merged
ZhiXiao-Lin merged 1 commit into
mainfrom
feat/python-bootstrap-shim
May 24, 2026
Merged

feat(python-sdk): pure-Python bootstrap on PyPI fetches native wheels from GH Releases#45
ZhiXiao-Lin merged 1 commit into
mainfrom
feat/python-bootstrap-shim

Conversation

@ZhiXiao-Lin
Copy link
Copy Markdown
Contributor

Closes the gap left by #44, which moved native wheels off PyPI but broke `pip install a3s-code` for everyone except cp310 macOS arm64.

What this PR does

Adds a tiny pure-Python package (also named `a3s-code`) that goes to PyPI. On first `import a3s_code` it:

  1. Resolves the matching native wheel name for the current interpreter + platform.
  2. Downloads it from `https://github.com/AI45Lab/Code/releases/download/v/`.
  3. Fetches `python-native-manifest.json` from the same release and verifies the wheel's sha256.
  4. Extracts the compiled `_native..{so,pyd}` to `~/.cache/a3s-code//` (or `$XDG_CACHE_HOME/a3s-code//`, or `$A3S_CODE_CACHE_DIR//`).
  5. Registers it as `sys.modules["a3s_code._native"]` via `importlib.machinery.ExtensionFileLoader` so `from ._native import *` in the package `init` works.

Subsequent imports skip the download.

```bash
pip install a3s-code # downloads the bootstrap (tiny)
python -c 'import a3s_code' # first call: fetches native wheel from GH Release (~17 MB)
python -c 'import a3s_code' # second call: uses cache, instant
```

Layout

```
sdk/python-bootstrap/
├── pyproject.toml # setuptools, pure-Python, no deps
├── README.md
├── src/a3s_code/
│ ├── init.py # bootstrap() then from ._native import *
│ ├── _bootstrap.py # loader logic
│ └── py.typed
└── tests/test_bootstrap.py # 15 unit tests + 1 live test
```

Env knobs

Variable Effect
`A3S_CODE_CACHE_DIR` Cache root (defaults to `$XDG_CACHE_HOME/a3s-code` or `~/.cache/a3s-code`)
`A3S_CODE_RELEASES_BASE_URL` Override release base URL (air-gapped mirrors)
`A3S_CODE_SKIP_HASH_CHECK` `1` skips sha256 verification (CI only)

Workflow integration

  • New `publish-python-bootstrap.yml` — runs bootstrap unit tests, builds wheel + sdist, twine check, twine upload on tag push.
  • `release.yml` wires it in after `publish-python` (which produces the GH Release the bootstrap points at). `github-release` job now waits on both.
  • `scripts/check_release_versions.sh` validates the bootstrap's pyproject.toml version AND the runtime `version` literal — they must equal the core version so the bootstrap points at the right GH Release tag.
  • `release.sh` bumps both in lockstep.

Test plan

  • 15 unit tests pass (`python -m unittest tests.test_bootstrap`).
  • Live download test passes against the real v3.2.0 GH Release wheels (`A3S_CODE_BOOTSTRAP_LIVE=1`).
  • End-to-end: built the wheel locally, pip-installed into a fresh venv, ran `import a3s_code` with `version` temporarily patched to `3.2.0` (since the GH Release for 3.2.1 doesn't exist yet). Bootstrap downloaded the cp312 macOS arm64 wheel, extracted `_native.cpython-312-darwin.so` into the cache, registered it, and `a3s_code.Agent.create()` succeeded.
  • `scripts/check_release_versions.sh` reports consistent at 3.2.1.
  • `cargo test -p a3s-code-core --lib`: 1661 passed (unaffected).
  • `cargo fmt --all` clean.

Bumps

Core / Node SDK / Python SDK 3.2.0 → 3.2.1.

Release sequence after this PR merges

  1. Merge this PR to main.
  2. Tag `v3.2.1`, push.
  3. release.yml fires:
    • crates.io: `a3s-code-core 3.2.1`
    • npm: `@a3s-lab/code 3.2.1` + platform packages
    • GH Release v3.2.1: 12 native wheels + python-native-manifest.json
    • PyPI: `a3s-code 3.2.1` (the bootstrap, ~6 KB pure-Python wheel + sdist)
    • GH Release page with auto-generated notes

Optional follow-ups

… from GH Releases

After v3.2.0 stopped publishing native wheels to PyPI (PR #44, GH
Releases is the canonical host), `pip install a3s-code` was broken on
every platform except cp310 macOS arm64 (the one wheel that snuck into
PyPI before the 10 GB project cap kicked in).

This commit restores `pip install a3s-code` by adding a tiny
pure-Python bootstrap package — also named `a3s-code` — that on first
`import a3s_code` downloads the matching native wheel for the current
interpreter and platform, verifies its sha256 against the release
manifest, extracts the compiled `_native` extension into a per-user
cache, and registers it as `sys.modules["a3s_code._native"]`.
Subsequent imports use the cache; cold start is one download per
(version, platform, interpreter) triple.

New package
- sdk/python-bootstrap/ — setuptools-built pure-Python wheel
  (a3s_code-X.Y.Z-py3-none-any.whl) and matching sdist.
  - src/a3s_code/__init__.py — calls ensure_native_loaded() then
    `from ._native import *`.
  - src/a3s_code/_bootstrap.py — wheel-name resolver, downloader,
    sha256 verifier, extension loader. Knobs: A3S_CODE_CACHE_DIR,
    A3S_CODE_RELEASES_BASE_URL, A3S_CODE_SKIP_HASH_CHECK.
  - tests/test_bootstrap.py — 15 unit tests (filename resolution,
    cache dir, sha256 mismatch, idempotency, manifest fallback) plus
    one live download test gated on A3S_CODE_BOOTSTRAP_LIVE=1.
  - README documenting install model and overrides.

Workflow
- publish-python-bootstrap.yml — runs bootstrap unit tests, builds
  wheel + sdist, twine check, twine upload on tag push.
- release.yml — adds the bootstrap publish job; runs after
  publish-python (which produces the GH Release the bootstrap points
  at) and gates github-release on both.

Release plumbing
- scripts/check_release_versions.sh now validates the bootstrap
  pyproject.toml and the runtime __version__ in _bootstrap.py — they
  must equal the core version so the bootstrap finds the matching GH
  Release tag.
- release.sh bumps both in lockstep with the other version files.
- README + sdk/python README rewritten to advertise pip install
  a3s-code again and explain the cache.

Bumps core / Node SDK / Python SDK from 3.2.0 to 3.2.1 since the
bootstrap is a user-facing addition. CHANGELOG [3.2.1] entry
documents the new package + rationale.

End-to-end verified locally: built the wheel, installed into a fresh
venv, ran `import a3s_code` with __version__ patched to 3.2.0 so the
bootstrap points at the real GH Release; Agent.create succeeded.
@ZhiXiao-Lin ZhiXiao-Lin merged commit 6499123 into main May 24, 2026
1 check passed
@ZhiXiao-Lin ZhiXiao-Lin deleted the feat/python-bootstrap-shim branch May 24, 2026 02:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants