Skip to content

fix(python-sdk): use per-event-loop transport for async client#1178

Open
joe-lombrozo-s-bot[bot] wants to merge 3 commits intomainfrom
fix/async-transport-per-event-loop
Open

fix(python-sdk): use per-event-loop transport for async client#1178
joe-lombrozo-s-bot[bot] wants to merge 3 commits intomainfrom
fix/async-transport-per-event-loop

Conversation

@joe-lombrozo-s-bot
Copy link
Contributor

Problem

The async get_transport() in the Python SDK uses a single class-level singleton (AsyncTransportWithLogger.singleton) to share one transport across all callers. This assumes all async callers use the same asyncio event loop.

This is an invalid assumption. Transports can be requested from different event loops when:

  • asyncio.run() is called multiple times (each creates a new loop)
  • Multiple threads each run their own event loop
  • Test frameworks create fresh loops per test

Since httpx async transports are bound to the event loop they were first used on, reusing a transport from a different loop causes errors.

Fix

Replace the single singleton class variable with a _instances dict keyed by id(asyncio.get_running_loop()). Each event loop gets its own transport instance while still sharing within the same loop for connection pooling benefits.

The sync version doesn't have this issue since there's no event loop binding involved.

Changes

  • packages/python-sdk/e2b/api/client_async/__init__.py: Replace singleton with per-loop dict lookup

The async get_transport() used a single class-level singleton, which
assumes all callers share the same asyncio event loop. This breaks when
the SDK is used across multiple event loops (e.g. multiple asyncio.run()
calls, or threads with their own loops), because httpx async transports
are bound to the loop they were first used on.

Replace the singleton with a dict keyed by id(asyncio.get_running_loop())
so each event loop gets its own transport instance while still sharing
within the same loop for connection pooling benefits.
@changeset-bot
Copy link

changeset-bot bot commented Mar 5, 2026

🦋 Changeset detected

Latest commit: 3ab5af6

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

@github-actions
Copy link
Contributor

github-actions bot commented Mar 5, 2026

Package Artifacts

Built from 978c45b. Download artifacts from this workflow run.

JS SDK (e2b@2.14.2-fix-async-transport-per-event-loop.0):

npm install ./e2b-2.14.2-fix-async-transport-per-event-loop.0.tgz

CLI (@e2b/cli@2.8.1-fix-async-transport-per-event-loop.0):

npm install ./e2b-cli-2.8.1-fix-async-transport-per-event-loop.0.tgz

Python SDK (e2b==2.15.1+fix-async-transport-per-event-loop):

pip install ./e2b-2.15.1+fix.async.transport.per.event.loop-py3-none-any.whl

@djeebus djeebus marked this pull request as ready for review March 6, 2026 19:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants