Skip to content

Commit c023b3c

Browse files
mishushakovclaude
andcommitted
Revert "fix(python): build own HTTP/1.1 transport for Jupyter requests"
This reverts commit d268be9. Duplicating the SDK's transport internals here only deepened the private-API coupling that broke in the first place, so the HTTP-version option is going upstream instead — see .context/upstream-http1-transport-proposal.md. The `get_transport(config, http2=False)` call sites are the end state already and need no change once e2b restores the parameter; the Python floor in pyproject.toml then moves to that release. Until it ships, the Python half of this bump cannot pass CI. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent d268be9 commit c023b3c

4 files changed

Lines changed: 34 additions & 103 deletions

File tree

.changeset/shaggy-plums-wave.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,4 @@
33
'@e2b/code-interpreter-python': patch
44
---
55

6-
Bump the E2B SDK dependency: JavaScript to 2.38.3, Python to 2.38.0.
7-
8-
The Python SDK moved its HTTP stack onto [`pyqwest`](https://pypi.org/project/pyqwest/), and its internal `get_transport()` helper no longer takes an `http2` argument — the HTTP version is negotiated by ALPN instead, which means HTTP/2 against the sandbox. Jupyter requests build their own HTTP/1.1 transport now (`e2b_code_interpreter.transport`), from the same pool tuning and connect-only retry policy the SDK uses, so client disconnects keep propagating to the server as a TCP close and long-running executions stay reliably cancellable.
6+
Bump E2B SDK dependency: JavaScript to 2.38.3, Python to 2.38.0

python/e2b_code_interpreter/code_interpreter_async.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
AsyncSandbox as BaseAsyncSandbox,
99
InvalidArgumentException,
1010
)
11-
from e2b_code_interpreter.transport import get_async_transport
11+
from e2b.api.client_async import get_transport
1212

1313
from e2b_code_interpreter.constants import (
1414
DEFAULT_TEMPLATE,
@@ -70,11 +70,23 @@ def _jupyter_url(self) -> str:
7070

7171
@property
7272
def _client(self) -> AsyncClient:
73-
# Use a dedicated HTTP/1.1 transport for Jupyter requests so that
74-
# client disconnects propagate to the server; see the module docstring
75-
# of `e2b_code_interpreter.transport`.
73+
# TODO: Remove later
74+
# Use a dedicated HTTP/1.1 transport for Jupyter requests.
75+
#
76+
# The base SDK's shared transport now defaults to http2=True. With
77+
# HTTP/2, multiple requests are multiplexed over a single TCP
78+
# connection, so when a client cancels a request (e.g. the caller
79+
# disconnects from the streaming `/execute` endpoint) the server
80+
# may not detect the disconnect: only the HTTP/2 stream is
81+
# cancelled, the underlying TCP connection stays open.
82+
#
83+
# Forcing HTTP/1.1 here keeps the 1:1 mapping between TCP
84+
# connection and request, so client disconnects propagate to the
85+
# server as a TCP close and long-running executions can be
86+
# cancelled reliably. The helper also caches the transport
87+
# per-event-loop for async.
7688
return AsyncClient(
77-
transport=get_async_transport(self.connection_config),
89+
transport=get_transport(self.connection_config, http2=False),
7890
)
7991

8092
async def _handle_connection_error(self, err: Exception) -> None:

python/e2b_code_interpreter/code_interpreter_sync.py

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from typing import Optional, Dict, overload, Union, List
55
from httpx import Client
66
from e2b import Sandbox as BaseSandbox, InvalidArgumentException
7-
from e2b_code_interpreter.transport import get_sync_transport
7+
from e2b.api.client_sync import get_transport
88

99
from e2b_code_interpreter.constants import (
1010
DEFAULT_TEMPLATE,
@@ -67,10 +67,21 @@ def _jupyter_url(self) -> str:
6767

6868
@property
6969
def _client(self) -> Client:
70-
# Use a dedicated HTTP/1.1 transport for Jupyter requests so that
71-
# client disconnects propagate to the server; see the module docstring
72-
# of `e2b_code_interpreter.transport`.
73-
return Client(transport=get_sync_transport(self.connection_config))
70+
# TODO: Remove later
71+
# Use a dedicated HTTP/1.1 transport for Jupyter requests.
72+
#
73+
# The base SDK's shared transport now defaults to http2=True. With
74+
# HTTP/2, multiple requests are multiplexed over a single TCP
75+
# connection, so when a client cancels a request (e.g. the caller
76+
# disconnects from the streaming `/execute` endpoint) the server
77+
# may not detect the disconnect: only the HTTP/2 stream is
78+
# cancelled, the underlying TCP connection stays open.
79+
#
80+
# Forcing HTTP/1.1 here keeps the 1:1 mapping between TCP
81+
# connection and request, so client disconnects propagate to the
82+
# server as a TCP close and long-running executions can be
83+
# cancelled reliably.
84+
return Client(transport=get_transport(self.connection_config, http2=False))
7485

7586
def _handle_connection_error(self, err: Exception) -> None:
7687
"""

python/e2b_code_interpreter/transport.py

Lines changed: 0 additions & 90 deletions
This file was deleted.

0 commit comments

Comments
 (0)