feat(sdks/python): resilient SDK transport (OSEP-0016)#1372
Conversation
317efb4 to
10c2023
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 10c20233ea
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
10c2023 to
f5ae605
Compare
|
To use Codex here, create a Codex account and connect to github. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f5ae605ec9
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
f5ae605 to
a62bac0
Compare
|
To use Codex here, create a Codex account and connect to github. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a62bac02a1
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
a62bac0 to
7e1af4c
Compare
|
To use Codex here, create a Codex account and connect to github. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7e1af4c685
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
7e1af4c to
929235a
Compare
|
To use Codex here, create a Codex account and connect to github. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 929235abf8
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
929235a to
2a0c6d2
Compare
|
To use Codex here, create a Codex account and connect to github. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2a0c6d280a
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
2a0c6d2 to
1f66734
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1f6673484b
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
1f66734 to
8685e37
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8685e37d79
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
Implement the Python side of OSEP-0016 for the sandbox and
code-interpreter SDKs. Adds a shared retry policy, extended
exception hierarchy, and async/sync httpx transport wrappers.
Retry policy
- New `RetryPolicy` value type on `ConnectionConfig` /
`ConnectionConfigSync`; defaults enable retry for idempotent
methods only, `POST`/`PATCH` status-code retry is opt-in.
- Default idempotent retryable status set: `{429, 502, 503}`.
- Decorrelated jitter (default), full jitter, and deterministic
exponential; `Retry-After` honored with a fixed 60s ceiling.
- `RetryPolicy.disabled()` gives end-to-end fast-fail semantics
and suppresses fresh-connection recovery.
- `HTTPStatus` used at the public API surface so callers get
type checking and IDE completion for the status sets.
Exception hierarchy
- Extend `SandboxException` with an `is_retryable` accessor
reflecting the SDK's actual retry decision at emission time.
- New subclasses: `SandboxRateLimitException` (carries
`retry_after`), `SandboxTimeoutException`,
`SandboxConnectionException`. Existing classes and their
public fields are unchanged.
Transport wrappers
- `RetryAsyncTransport` (httpx.AsyncBaseTransport) and
`RetrySyncTransport` (httpx.BaseTransport) install the retry
engine at the same layer the SDK already uses for transport
concerns. Generated OpenAPI code is not touched.
- `ConnectionConfig` exposes a `sse_transport` property so SSE
bootstraps bypass retry while sharing the underlying pool.
Command / isolated / code-interpreter SSE clients now use it.
- `lifecycle_metrics` keeps its own short-lived httpx.Client;
sharing the SDK transport would let the metrics client's
`close()` tear down every other adapter's connection pool.
Tests
- Retry policy defaults, validation, and `HTTPStatus` usage.
- Pure decision function: status matrix, transport branch,
budget/deadline/cancellation predicates, opt-in rules,
jitter algorithms, and `Retry-After` parsing/clamping.
- Async + sync httpx transport integration via scripted mock
transports covering success, 4xx pass-through, budget
exhaustion, pre-send vs. post-send classification, opt-in,
and observability callback invariants.
- `ConnectionConfig` wiring: default wraps, `disabled()` skips
wrapping, user-supplied transports are used verbatim.
- SSE clients use the raw inner transport, verified end-to-end.
8685e37 to
1525809
Compare
|
To use Codex here, create a Codex account and connect to github. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1525809a50
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
Summary
Python landing of OSEP-0016 Resilient SDK Transport for both
sdks/sandbox/pythonandsdks/code-interpreter/python. Client-only; no spec change, no server change, no wire-format change.Draft while OSEP-0016 is still under review; will be marked ready once the design lands (or updated to track any decision changes on the OSEP first).
What it adds
Retry policy (
opensandbox.transport.RetryPolicy)ConnectionConfig/ConnectionConfigSync.POST/PATCHstatus-code retry is opt-in throughretryable_status_codes_non_idempotent.{HTTPStatus.TOO_MANY_REQUESTS, HTTPStatus.BAD_GATEWAY, HTTPStatus.SERVICE_UNAVAILABLE}— narrower than the OSEP draft; happy to widen back to{408, 425, 429, 500, 502, 503, 504}if the OSEP thread lands there.Retry-Afterhonored with a fixed 60s ceiling to prevent pathological server headers from stalling the client.RetryPolicy.disabled()for end-to-end fast-fail (also suppresses fresh-conn recovery).frozenset[HTTPStatus]so callers get type checking and IDE completion.Exception hierarchy
SandboxExceptionwith anis_retryableaccessor reflecting the SDK's actual retry decision at emission time (budget exhaustion / deadline / cancellation all forceFalseeven for transient causes).SandboxRateLimitException(carriesretry_after),SandboxTimeoutException,SandboxConnectionException.except SandboxApiExceptioncontinues to catch rate-limit and API errors.Transport wrappers
RetryAsyncTransport(httpx.AsyncBaseTransport) andRetrySyncTransport(httpx.BaseTransport).ConnectionConfigexposes asse_transportproperty so SSE bootstraps bypass retry while sharing the underlying connection pool.sse_transport.lifecycle_metricspiggy-backs on the shared transport when possible, matching sync/async transport types.Behavior change to call out
RetryPolicyis enabled by default. Callers that rely on fast-fail semantics onGET/HEAD/PUT/DELETEmust opt out viaConnectionConfig(retry_policy=RetryPolicy.disabled()).POST/PATCHare never retried on any status code; pre-send transport failures (DNS, TCP connect, TLS handshake, fresh-conn RST) are still retried onPOST/PATCH.Non-goals
Matches OSEP-0016 non-goals: no server-side idempotency store, no per-request override, no SSE stream resume, no client-side circuit breaker.
Tests
HTTPStatususage.Retry-Afterparsing and clamping.ConnectionConfigwiring: default wraps,disabled()skips wrapping, user-supplied transports pass through verbatim._httpx_client._transportvs_sse_client._transport).Local verification (macOS, Python 3.12):
sdks/sandbox/python:uv run ruff checkclean,uv run pyrightclean on this PR's files,uv run pytest396 passed.sdks/code-interpreter/python:uv run ruff checkclean,uv run pyrightclean,uv run pytest15 passed.Follow-ups
Last-Event-ID— deferred to a follow-up OSEP as noted in OSEP-0016.Related