fix(python-sdk): restore the http2 parameter on the transport factories - #1671
Conversation
The pyqwest migration in 2.38.0 dropped `http2` from `get_transport` and `get_envd_transport`, so `get_transport(config, http2=False)` — which e2b-code-interpreter uses for its Jupyter requests — now raises `TypeError`. pyqwest supports the capability (`http_version`), it just was not threaded through. `http2=False` again returns a transport pinned to HTTP/1.1, on its own pool: the HTTP version is back in both cache keys, so a caller can never be handed a transport of the other version. The default is unchanged — `http_version=None` leaves TLS connections to ALPN (HTTP/2 against the E2B API) and uses HTTP/1 for plaintext. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Code review is billed via overage credits. To resume reviews, an organization admin can raise the monthly limit at claude.ai/admin-settings/claude-code.
If your organization is eligible for promotional free reviews, this run could not use one — if free runs remain, retrying may succeed without raising the limit.
Once credits are available — or to retry now — reopen this pull request to trigger a review.
🦋 Changeset detectedLatest commit: 88ba9f8 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
PR SummaryMedium Risk Overview
Adds transport tests for cache separation, wiring into pyqwest, and HTTP/1.1 round trips, plus a patch changeset entry. Reviewed by Cursor Bugbot for commit 88ba9f8. Bugbot is set up for automated code reviews on this repo. Configure here. |
Package ArtifactsBuilt from 916004c. Download artifacts from this workflow run. JS SDK ( npm install ./e2b-2.39.1-abuja-v1.0.tgzCLI ( npm install ./e2b-cli-2.16.2-abuja-v1.0.tgzPython SDK ( pip install ./e2b-2.39.0+abuja.v1-py3-none-any.whl |
|
One note from the architect harness, if you wanna add it. Nothing guards against re-dropping the parameter. The break happened because a de-facto-public signature changed silently, and the new tests all pass http2= as a keyword — so moving it behind * or renaming it keeps the suite green and breaks e2b-code-interpreter again. Cheapest fix: a one-line comment on both factories naming the external consumer (e2b-code-interpreter reaches into this — #1347 / SDK-335), optionally an inspect.signature assertion. The comment alone would likely have prevented the original drop. |
Nothing is held back on my judgement any more. What moved: e2b cap >=2.26,<2.38 -> >=2.39,<3 plus the notebook "e2b<2.38" e2b-code-interpreter ==2.9.0 -> ==2.9.1 tailwindcss ^3.4.17 -> ^4.3.3 (migration, see below) http-proxy-middleware ^3.0.5 -> ^4.2.0 open ^10.2.0 -> ^11.0.1 eve ^0.33.3 -> ^0.38.3 anthropic ==0.121.0 -> ==0.122.0 mistralai ==2.9.2 -> ==2.9.3 firecrawl-py ==4.35.0 -> ==4.35.1 together ==2.30.0 -> ==2.31.0 ibm_watsonx_ai ==1.6.1 -> ==1.6.3 The e2b cap is gone because 2.39.1 works with code-interpreter again - verified live against a clean install, run_code returns - so e2b-dev/E2B#1671 landing has undone the reason for it. Tailwind 4 is a migration, not a bump: the @tailwind directives collapse to one @import, the PostCSS plugin becomes @tailwindcss/postcss, autoprefixer is bundled in and dropped, content paths are auto-detected so tailwind.config.js is deleted, and the gradient theme extensions move into an @theme block in globals.css. Verified with a real next build. http-proxy-middleware 4 requires Node ^22.15 || ^24 || >=26 and the E2B base template ships Node 20.9 - checked in a live sandbox rather than assumed, alongside Python 3.11.6. Rather than hold the dependency back, examples can now declare a nodeVersion and the runner fetches that Node tarball into the sandbox first. Pinned tarball, not a piped installer. Two things stay where they are, both because the ecosystem has not moved rather than because I chose it. typescript stays ^5.9.3 in codestral-code-interpreter-js and together-ai-code-interpreter-js: typescript-eslint peers on typescript >=4.8.4 <6.1.0 in every published version including its newest 8.67.1 alphas, so TS 7 cannot resolve there. And `open` turned out to need only Node >=20, so holding it back earlier was my error, not a constraint - it went up with this batch. Verified: every JS example installs and typechecks, all 117 notebook cells compile, the Next.js app builds on Tailwind 4, and no e2b cap remains anywhere.
The http2 parameter came back in @e2b/python-sdk 2.39.1 (#1671), not 2.38.1 — the Python SDK has no 2.38.1 release. Changeset prose lands verbatim in the published CHANGELOG, so the wrong pin would mislead anyone looking for which release keeps http2 working. Co-authored-by: Mish Ushakov <mishushakov@users.noreply.github.com>
The pyqwest migration in 2.38.0 dropped the
http2parameter fromget_transportandget_envd_transport(added deliberately in #1347, 2.32.0) and collapsed the transport cache key to the proxy alone, soe2b-code-interpreter's Jupyter requests —get_transport(self.connection_config, http2=False)— now raiseTypeError: get_transport() got an unexpected keyword argument 'http2'; that is already live, sincee2b = "^2.26.0"resolves to 2.38.x, and it blocks the Python half of code-interpreter #328. pyqwest supports the capability, it just was not threaded through: this restores the pre-2.38.0 signature (so no consumer code changes, only ane2bfloor bump) by passinghttp_version=None if http2 else HTTPVersion.HTTP1into the pyqwest transports, and puts the HTTP version back into both cache keys — without that, whichever caller asks second is handed a transport of the wrong version. The default is unchanged:Noneleaves TLS connections to ALPN (HTTP/2 against the E2B API) and uses HTTP/1 for plaintext, exactly as today. HTTP/1.1 is not cosmetic for the consumer — with HTTP/2 multiplexing, abandoning a request only resets its stream, so the code-interpreter server never sees thehttp.disconnectit needs to interrupt the kernel, while HTTP/1.1's one connection per request closes the connection and the server observes it.Usage
Both factories are internal (nothing is exported from
e2b/__init__.py), so there is no public API change; consumers reaching into them get the 2.32.0 call back:The async mirror (
e2b.api.client_async) is identical.Tests
Six new cases in
packages/python-sdk/tests/test_api_client_transport.py, sync and async: cache separation and identity acrosshttp2/ proxy /for_streaming, thehttp_versionvalue actually reaching the pyqwest transport ([None, HTTP1, HTTP1]), and a round trip proving the pinned transport works. The negotiated version can't be observed locally — the test echo server is plaintext, where both settings speak HTTP/1 — so it is asserted at the constructor, with the reason in a comment; it was verified by hand againsthttps://api.e2b.app/healthvia thepyqwest.accesslogger, which shows"HTTP/2 200 OK"on the default and"HTTP/1.1 200 OK"withhttp2=Falseon both factories (and confirmshttpx.Response.http_versionis unreliable through the adapter — it reports HTTP/1.1 either way). 256 unit tests pass, plusmake lint,make typecheckandmake format. No JS change: its transport is an undici-dispatcherfetchwith no HTTP-version knob, and the JS half of code-interpreter #328 is a clean bump.Closes SDK-335
🤖 Generated with Claude Code