Skip to content

feat: normalize the surface interface of Python SDK#73

Merged
christianalfoni merged 3 commits intomainfrom
CSB-1419
May 8, 2026
Merged

feat: normalize the surface interface of Python SDK#73
christianalfoni merged 3 commits intomainfrom
CSB-1419

Conversation

@christianalfoni
Copy link
Copy Markdown
Collaborator

@christianalfoni christianalfoni commented May 8, 2026

Normalize the Python SDK surface to flat keyword arguments

The Python SDK previously required users to import auto-generated request/body classes (CreateSandboxBody, CreateExecRequest, ExecStdin, StartOptions, CreateSandboxParams) and pass them as a single body or params argument. This branch flattens the public surface so calls read like idiomatic Python — no auto-generated types in user code, no StartOptions(...) wrappers — and folds in the new retry plumbing from main.

❌ Current behavior

from together_sandbox import StartOptions, CreateSandboxParams
from together_sandbox.api.models.create_sandbox_body import CreateSandboxBody
from together_sandbox.sandbox.models.create_exec_request import CreateExecRequest
from together_sandbox.sandbox.models.update_exec_request import UpdateExecRequest
from together_sandbox.sandbox.models.exec_stdin import ExecStdin

# Sandbox lifecycle — wrap everything in body objects
sandbox = await sdk.sandboxes.create(CreateSandboxParams(
    millicpu=1000, memory_bytes=2_000_000_000, disk_bytes=10_000_000_000,
    snapshot_alias="my-app@v1",
))
sb = await sdk.sandboxes.start(sandbox.id, start_options=StartOptions(version_number=3))

# Exec — wrap, then call generic update() with a status enum
exec_ = await sb.execs.create(CreateExecRequest(
    command="npm", args=["start"], cwd="/workspace",
))
await sb.execs.update(exec_.id, UpdateExecRequest(status="running"))
await sb.execs.send_stdin(exec_.id, ExecStdin(input="ls\n"))
# (no resize method)

✅ New behavior

# Sandbox lifecycle — flat kwargs, no body imports
sandbox = await sdk.sandboxes.create(
    millicpu=1000, memory_bytes=2_000_000_000, disk_bytes=10_000_000_000,
    snapshot_alias="my-app@v1",
)
sb = await sdk.sandboxes.start(sandbox.id, version_number=3)

# Exec — flat kwargs, intent-named verbs
exec_ = await sb.execs.create(
    "npm", ["start"], cwd="/workspace", env={"NODE_ENV": "production"},
)
await sb.execs.resume(exec_.id)              # was execs.update(..., status="running")
await sb.execs.send_stdin(exec_.id, "ls\n")  # raw str, no ExecStdin wrapper
await sb.execs.resize(exec_.id, cols=80, rows=24)  # new

🤔 Assumptions

  • Users never directly construct CreateSandboxBody / CreateExecRequest / ExecStdin — they're internal wire types, not API ergonomics.
  • The only valid update_exec status today is "running", so update() is best modeled as resume().
  • The PTY wire format "{cols}x{rows}" for resize is what the agent expects (flagged in the docstring as not yet end-to-end verified).
  • The retry config (RetryConfig / RetryContext) introduced on main should be re-exported from the package root alongside the other public types.

🧠 Decisions

  • Normalized op-names to a dotted convention everywhere ("sandboxes.start", "sandboxes.wait", "sandboxes.create", "execs.resume", "execs.sendStdin", "execs.resize") so users filtering on RetryContext.operation see a consistent namespace.
  • Deleted together_sandbox/_types.py (StartOptions, CreateSandboxParams) — the flat-kwargs signatures replace them entirely.
  • Kept the auto-generated body classes available as imports for advanced users, but no longer reference them in the surface API or docs.

🔄 Discussions

  • Mid-merge, the _call_api-based tests fail when mocks return bare model instances instead of Response[...] wrappers. Added the make_api_response / make_sandbox_response helpers to every patched mock and updated the error-path tests' regex matchers to the dotted op-name format.
  • _sandboxes.py originally landed three camelCase op-names from main. Renamed to dotted form during the merge so retry hooks see the same convention across the package.

🧪 Testing

  • Conflict resolution verified: git grep '<<<<<<< \|=======$\|>>>>>>> ' returns nothing across the workspace.
  • Updated unit tests in together-sandbox-python/tests/test_facade.py cover: SandboxesNamespace.create body construction (required-only + all optional kwargs), Execs.create flat-kwargs and env dict wrapping, Execs.resume sending RUNNING, Execs.send_stdin and Execs.resize body shapes, plus error-path matchers for the new dotted op-names.
  • pytest tests/ -v passes locally.

📁 References

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Note! This file is deleted in the E2E tests PR, so can just ignore it

@christianalfoni christianalfoni merged commit 8a7e59a into main May 8, 2026
4 checks passed
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