Skip to content

feat(sdk/python): API parity with sdk/rust + guest-agent (0.5.4b1)#695

Draft
Leechael wants to merge 7 commits into
feat/sdk-release-workflowsfrom
feat/sdk-python-api-parity
Draft

feat(sdk/python): API parity with sdk/rust + guest-agent (0.5.4b1)#695
Leechael wants to merge 7 commits into
feat/sdk-release-workflowsfrom
feat/sdk-python-api-parity

Conversation

@Leechael
Copy link
Copy Markdown
Collaborator

Stacked on #690. Base branch: feat/sdk-release-workflows.

Brings the Python SDK in line with sdk/rust and the guest-agent 0.5.7 proto, mirroring the JS work that landed in #690.

Atomic commits

  1. chore(sdk/python): read __version__ from package metadata — drops the hard-coded "0.5.2" that was drifting from pyproject.toml; uses importlib.metadata.
  2. feat(sdk/python): surface cloud_vendor and cloud_product on InfoResponse — exposes AppInfo proto fields 15/16 (dstack OS >= 0.5.7).
  3. feat(sdk/python): add not_before/not_after/with_app_info TLS key options — kw-only params backed by a Version-RPC gate, same pattern as ed25519 algorithm gating.
  4. feat(sdk/python)!: real ECDSA recovery for verify_env_encrypt_public_keybreaking change:
    • verify_env_encrypt_public_key now requires a timestamp: int arg and performs real secp256k1 + Keccak256 recovery (eth-keys + eth-utils).
    • Adds verify_env_encrypt_public_key_legacy (DeprecationWarning) for old KMS builds.
    • Removes verify_signature_simple (was an always-True stub).
    • Adds eth-keys + eth-utils to core deps (pure Python; vmm-cli already ships them).
  5. chore(sdk/python): trim ethereum extras from web3 to eth-accountethereum.py only ever used eth_account; drops ~780 lines from the lockfile.
  6. docs(sdk/python): rewrite README for 0.5.4b1 API surface — covers the new API surface and adds a Compatibility table tying each feature to its required OS version.
  7. chore(sdk/python): bump to 0.5.4b1 for API parity beta — test release.

Breaking changes

Two surface-level breaks, both isolated to the env-encrypt verification helper:

Before After
verify_env_encrypt_public_key(public_key, signature, app_id) verify_env_encrypt_public_key(public_key, signature, app_id, timestamp, *, max_age_seconds=300)
verify_signature_simple(...) removed (was always-True stub)

Callers stuck on legacy non-timestamped signatures can use the new verify_env_encrypt_public_key_legacy() helper (emits a DeprecationWarning).

Test plan

  • CI green on sdk/python job
  • pytest tests/test_verify_env_encrypt_public_key.py — 17 passed locally
  • pytest tests/test_client.py::test_get_tls_key_* — 3 mock-based payload tests passed
  • Smoke import in fresh pdm install (default group only, no extras)
  • Integration test against simulator after merge

Leechael added 7 commits May 20, 2026 22:12
Replace the hard-coded "0.5.2" string in dstack_client.py with
importlib.metadata.version("dstack-sdk") so the User-Agent header always
matches the installed pyproject version. Falls back to "0.0.0+unknown"
when running uninstalled.
Expose the two AppInfo proto fields (15, 16) added on dstack OS >= 0.5.7
so Python callers can identify the cloud provider that hosts the CVM.
Both default to empty string for backward compatibility with older guest
agents that omit them.

Mirrors the JS SDK change in f5ad5be.
Extend get_tls_key with the three GetTlsKeyArgs proto fields (6/7/8)
added on dstack OS >= 0.5.7. New params are kw-only so positional call
sites keep working unchanged. When any new option is provided, the SDK
probes the Version RPC first and raises a clear error on older OS images
that lack it (same gating pattern as ed25519 key derivation).

Mirrors the JS SDK change in dc5fc21.
Replace the stub (always returned None) with a real secp256k1 + Keccak256
implementation backed by eth-keys + eth-utils. Adds the timestamped
signature_v1 path the KMS now emits to defeat replay, while keeping a
verify_env_encrypt_public_key_legacy fallback (with DeprecationWarning)
for older KMS builds.

BREAKING CHANGES:
- verify_env_encrypt_public_key now requires a `timestamp: int` arg and
  performs real signature recovery. Callers using the old 3-arg form
  must switch to verify_env_encrypt_public_key_legacy (deprecated).
- verify_signature_simple has been removed. It was an always-True
  placeholder that did no real verification.

eth-keys and eth-utils are added to core dependencies (both pure-Python,
already used by vmm-cli for the same flow). Round-trip and known-vector
tests cover signature length, timestamp expiry/skew, custom max_age,
malformed app_id, and tamper detection.

Mirrors the JS SDK behavior in 3539db3 + 24eccb4.
ethereum.py only imports eth_account. Pulling all of web3 (aiohttp,
websockets, requests, urllib3, ...) for one helper is wasteful — drop
~780 lines from the lockfile by depending on eth-account directly.

Users still get the same to_account / to_account_secure entrypoint with
no API change. The 'all' / 'eth' / 'ethereum' extras now resolve to
eth-account>=0.13.0.
Rebuild the README around the current capability set, matching the
recently-rewritten JS README (7536c6c). Highlights:

- Installation extras table (ethereum, solana, all + aliases).
- New surface coverage: attest, sign/verify, version, is_reachable,
  emit_event, cloud_vendor/cloud_product on info, not_before/not_after/
  with_app_info on get_tls_key (with version-gating note).
- KMS env-encrypt section walks through the signature_v1 timestamp flow
  with a legacy fallback, replacing the stub-era guidance.
- Adds a Compatibility table tying each feature to its required dstack
  OS version.

Reviewed for AI slop, passive voice, redundant phrases, and sentence
length per the doc-review/copy rule set.
Test release covering the API-parity work in this PR:
- importlib.metadata-backed __version__
- cloud_vendor / cloud_product on InfoResponse
- not_before / not_after / with_app_info on get_tls_key (0.5.7+ gated)
- real ECDSA recovery in verify_env_encrypt_public_key, with timestamp
  v1 + legacy fallback (BREAKING: 4th positional arg required; the old
  no-op verify_signature_simple is removed)
- ethereum extras now resolve to eth-account instead of full web3
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.

1 participant