Repository navigation
Description
User Story
As a maintainer of the Python SDK, I want to move it out of core into ai-openshell/sdk-python the way the Go SDK moved (#5031), so that it gets its own CI, reviews and releases without changing anything for the people who pip install openshell.
Problem Statement
RFC 0019 (#4426) moves the SDKs out of core first. The Python SDK still lives in core, spread across several paths:
python/openshell/, plus its SDK tests inpython/;- the repository-root
pyproject.toml, which is the SDK's package definition; tasks/python.toml;tasks/scripts/generate_python_proto.pyandverify-python-wheel.py.
Core CI builds, lints and type-checks the SDK on every PR. Core's release workflows build the wheel and publish it to PyPI through wheel-publish.yml, and the openshell PyPI project trusts only that workflow. Core's e2e/python suites import the SDK from the working tree. The root uv.lock serves both the SDK and core's own Python tooling.
Impact / Why This Matters
- SDK maintainers own CI, reviews and releases without core review bandwidth, which is the goal of RFC 0019.
- Users see no change. The package name
openshell, the import paths and the API stay the same, includingopenshell._proto. Public code on GitHub depends on that module: Airflow's sandbox provider, dify-agent, NeMo Gym and others import it directly. So the move must not be combined with a breaking change to the generated bindings. - Core stops building and publishing the Python wheel. Its e2e suites consume the SDK as a pinned dependency.
Proposed Design
Follow the Go SDK's phases (#5031, and the lessons in discussion 5273), adapted to Python:
- Prerequisites.
- Confirm the
sdkteam and the sdk-python repository settings. - Plan the PyPI trusted-publisher handover and the version scheme. The first release from sdk-python must sort after the last core-built wheel.
- Announce the freeze at a release tag and merge the SDK PRs that are ready before it.
- Confirm the
- Import.
- Extract the SDK paths with history, using
git filter-repo --paths-from-file: the package moves tosrc/openshell/, the tests totests/and the scripts toscripts/. Core-only tests stay in core, and#Nreferences are rewritten toNVIDIA/OpenShell#N. - A second PR makes the package build on its own: bindings generated from protos fetched at the pinned core tag and committed, vendored test fixtures with drift checks, and standalone CI with a Python 3.11–3.14 test matrix.
- Extract the SDK paths with history, using
- Cutover in core.
- Switch
e2e/pythonto the SDK as a pinned dependency. - Remove the
pythonjob andbuild:python:wheelfrom PR gating. - Add a required check that fails on changes to the moved paths, and port the open SDK PRs.
- Move the open SDK issues. GitHub can't transfer issues between organizations, so
gh issue transferfrom NVIDIA/OpenShell to ai-openshell isn't available.- Triage the open Python SDK issues in core. Close the ones already fixed or obsolete.
- Recreate each one that's still valid in sdk-python, with a link back to the original.
- Comment on each original with the new link, and close it as moved.
- Keep issues about core's own Python tooling or e2e suites in core (for example bug(test): Python E2E cleanup deadline is shorter than Kubernetes sandbox termination #4685).
- Today's candidate is bug(python): OIDC refresh drops the gateway's oidc_scopes #4919 (OIDC refresh drops the gateway's
oidc_scopes).
- Route new reports to sdk-python. Point core's issue templates (the
config.ymlcontact links) and CONTRIBUTING at sdk-python for Python SDK reports.
- Switch
- Automation in sdk-python. As planned for sdk-go: bump PRs for each core release, E2E against that release's gateway, release tagging and a nightly drift check.
- Retire in core.
- Ship a final core-built wheel with a deprecation note.
- Remove the SDK paths,
tasks/python.tomlSDK tasks, CodeQL entries, the wheel build andpublish-pypijobs,wheel-publish.yml, and core's PyPI trusted publisher. - Update
docs/sdk/python.mdx, AGENTS.md, CONTRIBUTING and the skills.
- Release. Publish the first
openshellrelease from sdk-python.
Progress:
- History import, frozen at
v0.1.7: chore: import the Python SDK history from NVIDIA/OpenShell ai-openshell/sdk-python#2. - Standalone build, test and packaging, with a Python 3.11–3.14 CI matrix: feat: build, test, and package the Python SDK standalone ai-openshell/sdk-python#3.
- An earlier draft, feat!: package sdk with public Buf protos ai-openshell/sdk-python#1, bootstraps from copied sources and switches the bindings to Protobuf-Py. That breaking change is better done after the move, as its own announced release.
Acceptance Criteria
- ai-openshell/sdk-python builds, tests and packages the SDK without a core checkout or network access at build time.
- The first release from sdk-python installs as a drop-in replacement for the last core-built wheel: same exports and the same
openshell._protomodules. - Core CI, releases and
e2e/pythonno longer build the SDK frompython/, and core proto PRs no longer regenerate Python bindings. - PyPI publishes
openshellonly from sdk-python. - No open Python SDK issues remain in core: each is closed as fixed, obsolete, or moved, with a link to its sdk-python copy. Core's issue templates send new Python SDK reports to sdk-python.
- The Python-specific lessons are added to the migration playbook for the next repository move.
Alternatives Considered
- Bootstrap from a copy without history (feat!: package sdk with public Buf protos ai-openshell/sdk-python#1). This loses blame and authorship, and the Go move kept history.
- Generate bindings at build time from the Buf Schema Registry with remote plugins. Every wheel or sdist build would then need network access, which breaks sdist rebuilds, and it pairs with a runtime change that breaks users of
openshell._proto. - Keep the SDK in core and delegate through CODEOWNERS. RFC 0019 already weighs this option.
Agent Investigation
An agent mapped the SDK's footprint in core (paths, mise tasks, workflows, CodeQL, PyPI publishing, e2e consumers), rehearsed the history extraction and the standalone build in a private repository, and surveyed public GitHub code that imports the SDK. Rehearsal results:
- 76 commits from 24 authors, with a tree hash that matches core.
- 34 imported commits are older core squash merges without
Signed-off-by, so the import PR needs a DCO override.
Activity