Skip to content

fix(python-sdk): restore the http2 parameter on the transport factories - #1671

Merged
mishushakov merged 1 commit into
mainfrom
abuja-v1
Aug 13, 2026
Merged

fix(python-sdk): restore the http2 parameter on the transport factories#1671
mishushakov merged 1 commit into
mainfrom
abuja-v1

Conversation

@mishushakov

Copy link
Copy Markdown
Member

The pyqwest migration in 2.38.0 dropped the http2 parameter from get_transport and get_envd_transport (added deliberately in #1347, 2.32.0) and collapsed the transport cache key to the proxy alone, so e2b-code-interpreter's Jupyter requests — get_transport(self.connection_config, http2=False) — now raise TypeError: get_transport() got an unexpected keyword argument 'http2'; that is already live, since e2b = "^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 an e2b floor bump) by passing http_version=None if http2 else HTTPVersion.HTTP1 into 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: None leaves 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 the http.disconnect it 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:

from e2b.api.client_sync import get_transport, get_envd_transport

# Unchanged: ALPN negotiates the version (HTTP/2 against the E2B API).
transport = get_transport(config)

# Its own pool, pinned to HTTP/1.1, so a cancelled request closes the
# connection and the server observes the disconnect.
http1 = get_transport(config, http2=False)
envd_http1 = get_envd_transport(config, http2=False)

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 across http2 / proxy / for_streaming, the http_version value 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 against https://api.e2b.app/health via the pyqwest.access logger, which shows "HTTP/2 200 OK" on the default and "HTTP/1.1 200 OK" with http2=False on both factories (and confirms httpx.Response.http_version is unreliable through the adapter — it reports HTTP/1.1 either way). 256 unit tests pass, plus make lint, make typecheck and make format. No JS change: its transport is an undici-dispatcher fetch with no HTTP-version knob, and the JS half of code-interpreter #328 is a clean bump.

Closes SDK-335

🤖 Generated with Claude Code

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>
@cla-bot cla-bot Bot added the cla-signed label Aug 13, 2026

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Code review skipped — your organization's overage spend limit has been reached.

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.

@linear-code

linear-code Bot commented Aug 13, 2026

Copy link
Copy Markdown

SDK-335

@changeset-bot

changeset-bot Bot commented Aug 13, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 88ba9f8

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@e2b/python-sdk Patch

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

@cursor

cursor Bot commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

PR Summary

Medium Risk
Changes shared transport caching and HTTP version selection for REST and envd traffic; default behavior is unchanged but incorrect cache keys before this fix could hand callers the wrong protocol pool.

Overview
Restores the http2 argument on internal get_transport and get_envd_transport in sync and async API clients after it was removed in the 2.38.0 pyqwest migration, which broke callers such as e2b-code-interpreter that pass http2=False.

http2=False again builds a separate pooled transport with pyqwest http_version=HTTPVersion.HTTP1; the default still uses ALPN (http_version=None). Transport caches now key on proxy plus http2 (and streaming for envd), so mixed callers do not share the wrong HTTP version pool.

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.

@github-actions

Copy link
Copy Markdown
Contributor

Package Artifacts

Built from 916004c. Download artifacts from this workflow run.

JS SDK (e2b@2.39.1-abuja-v1.0):

npm install ./e2b-2.39.1-abuja-v1.0.tgz

CLI (@e2b/cli@2.16.2-abuja-v1.0):

npm install ./e2b-cli-2.16.2-abuja-v1.0.tgz

Python SDK (e2b==2.39.0+abuja.v1):

pip install ./e2b-2.39.0+abuja.v1-py3-none-any.whl

@beran-t

beran-t commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

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.

@mishushakov
mishushakov merged commit 0d507cd into main Aug 13, 2026
25 of 26 checks passed
@mishushakov
mishushakov deleted the abuja-v1 branch August 13, 2026 15:56
beran-t added a commit to e2b-dev/e2b-cookbook that referenced this pull request Aug 17, 2026
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.
cursor Bot pushed a commit that referenced this pull request Aug 19, 2026
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants