Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .changeset/python-get-transport-http2-compat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
"@e2b/python-sdk": patch
---

Accept and ignore a deprecated `http2` argument on `get_transport` in both the
sync and async REST API clients. The pyqwest move dropped the parameter because
ALPN negotiates the HTTP version now, but every published
`e2b-code-interpreter` calls `get_transport(config, http2=False)`, and its
`e2b>=2.26.0,<3.0.0` range resolves straight to a version that no longer accepts
it. The result was a `TypeError` on the first `run_code()` of any fresh
`pip install e2b-code-interpreter`. The flag is inert, so it is accepted and
ignored rather than removed.
14 changes: 12 additions & 2 deletions packages/python-sdk/e2b/api/client_async/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,20 @@ def retrying_http_transport(
_transports: Dict[Optional[ProxyConfig], AsyncPyqwestTransport] = {}


def get_transport(config: ConnectionConfig) -> AsyncPyqwestTransport:
def get_transport(
config: ConnectionConfig, http2: Optional[bool] = None
) -> AsyncPyqwestTransport:
"""The shared pyqwest-backed httpx transport for REST API calls. For TLS
connections ALPN negotiates the HTTP version (HTTP/2 against the E2B
API), like the http2-enabled httpx transport this replaced."""
API), like the http2-enabled httpx transport this replaced.

:param http2: Deprecated and ignored. The httpx transport this replaced
took an explicit HTTP/2 switch; ALPN negotiates the version now, so
the flag no longer selects anything. Accepted so that callers written
against the pre-pyqwest signature keep working - notably every
published ``e2b-code-interpreter``, which calls
``get_transport(config, http2=False)``.
"""
proxy = proxy_to_config(config.proxy)
with _transport_lock:
transport = _transports.get(proxy)
Expand Down
14 changes: 12 additions & 2 deletions packages/python-sdk/e2b/api/client_sync/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,20 @@ def retrying_http_transport(
_transports: Dict[Optional[ProxyConfig], PyqwestTransport] = {}


def get_transport(config: ConnectionConfig) -> PyqwestTransport:
def get_transport(
config: ConnectionConfig, http2: Optional[bool] = None
) -> PyqwestTransport:
"""The shared pyqwest-backed httpx transport for REST API calls. For TLS
connections ALPN negotiates the HTTP version (HTTP/2 against the E2B
API), like the http2-enabled httpx transport this replaced."""
API), like the http2-enabled httpx transport this replaced.

:param http2: Deprecated and ignored. The httpx transport this replaced
took an explicit HTTP/2 switch; ALPN negotiates the version now, so
the flag no longer selects anything. Accepted so that callers written
against the pre-pyqwest signature keep working - notably every
published ``e2b-code-interpreter``, which calls
``get_transport(config, http2=False)``.
"""
proxy = proxy_to_config(config.proxy)
with _transport_lock:
transport = _transports.get(proxy)
Expand Down
26 changes: 26 additions & 0 deletions packages/python-sdk/tests/test_api_client_transport.py
Original file line number Diff line number Diff line change
Expand Up @@ -610,3 +610,29 @@ def test_sync_transport_sends_multipart_bodies(test_api_key, echo_server):
finally:
client.close()
reset_sync_api_transports()


def test_get_transport_accepts_the_deprecated_http2_kwarg(test_api_key):
"""Every published e2b-code-interpreter calls
``get_transport(config, http2=False)``. The pyqwest move dropped that
parameter, which turned the first ``run_code()`` of any fresh
``pip install e2b-code-interpreter`` into a TypeError, because
e2b-code-interpreter's ``e2b>=2.26.0,<3.0.0`` range resolves to a version
that no longer accepts it. The flag is inert now (ALPN negotiates), so it
is accepted and ignored rather than removed.
"""
reset_sync_api_transports()
reset_async_api_transports()
config = ConnectionConfig(api_key=test_api_key)

try:
# Ignored, so it must not key a separate cache entry.
assert get_sync_transport(config, http2=False) is get_sync_transport(config)
assert get_async_transport(config, http2=False) is get_async_transport(config)

# Positional still works, and so does omitting it entirely.
assert isinstance(get_sync_transport(config, False), PyqwestTransport)
assert isinstance(get_async_transport(config), AsyncPyqwestTransport)
finally:
reset_sync_api_transports()
reset_async_api_transports()
Loading