From 25ea9f7332b7791f9032999fdfed64b27dad038d Mon Sep 17 00:00:00 2001 From: Jakub Novak Date: Sat, 20 Sep 2025 19:16:38 +0200 Subject: [PATCH 01/23] Handle websocket error gracefully --- template/server/messaging.py | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/template/server/messaging.py b/template/server/messaging.py index e541351..e0f2cce 100644 --- a/template/server/messaging.py +++ b/template/server/messaging.py @@ -12,6 +12,7 @@ ) from pydantic import StrictStr from websockets.client import WebSocketClientProtocol, connect +from websockets.exceptions import ConnectionClosedError, WebSocketException from api.models.error import Error from api.models.logs import Stdout, Stderr @@ -275,7 +276,8 @@ async def execute( access_token: str, ): message_id = str(uuid.uuid4()) - self._executions[message_id] = Execution() + execution = Execution() + self._executions[message_id] = execution if self._ws is None: raise Exception("WebSocket not connected") @@ -319,7 +321,30 @@ async def execute( request = self._get_execute_request(message_id, complete_code, False) # Send the code for execution - await self._ws.send(request) + try: + await self._ws.send(request) + except (ConnectionClosedError, WebSocketException) as e: + logger.error(f"Failed to send execution request: {e}") + await execution.queue.put( + Error( + name="WebSocketError", + value="Failed to send execution request due to connection error", + traceback=str(e), + ) + ) + await execution.queue.put(UnexpectedEndOfExecution()) + return + except: + logger.error("Failed to send execution request due to unknown error") + await execution.queue.put( + Error( + name="WebSocketError", + value="Failed to send execution request due to unknown error", + traceback="", + ) + ) + await execution.queue.put(UnexpectedEndOfExecution()) + return # Stream the results async for item in self._wait_for_result(message_id): From 15b4f77e3d1f7029f2b455f58d952c866722b86f Mon Sep 17 00:00:00 2001 From: Jakub Novak Date: Sat, 20 Sep 2025 22:03:39 +0200 Subject: [PATCH 02/23] Lint --- template/server/messaging.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/template/server/messaging.py b/template/server/messaging.py index e0f2cce..6771b06 100644 --- a/template/server/messaging.py +++ b/template/server/messaging.py @@ -334,7 +334,7 @@ async def execute( ) await execution.queue.put(UnexpectedEndOfExecution()) return - except: + except: # noqa: E722 logger.error("Failed to send execution request due to unknown error") await execution.queue.put( Error( From 320d19f1cd0f088aea561ed0dc94fc1240266fa2 Mon Sep 17 00:00:00 2001 From: Jakub Novak Date: Sun, 21 Sep 2025 08:26:30 +0200 Subject: [PATCH 03/23] Remove early return --- template/server/messaging.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/template/server/messaging.py b/template/server/messaging.py index 6771b06..aff88e9 100644 --- a/template/server/messaging.py +++ b/template/server/messaging.py @@ -333,7 +333,6 @@ async def execute( ) ) await execution.queue.put(UnexpectedEndOfExecution()) - return except: # noqa: E722 logger.error("Failed to send execution request due to unknown error") await execution.queue.put( @@ -344,7 +343,6 @@ async def execute( ) ) await execution.queue.put(UnexpectedEndOfExecution()) - return # Stream the results async for item in self._wait_for_result(message_id): From 2d791d532f137bafa58ef3e4acdfcfc3c7b4206b Mon Sep 17 00:00:00 2001 From: Jakub Novak Date: Sun, 21 Sep 2025 18:28:28 +0200 Subject: [PATCH 04/23] Remove traceback --- template/server/messaging.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/template/server/messaging.py b/template/server/messaging.py index aff88e9..85ee947 100644 --- a/template/server/messaging.py +++ b/template/server/messaging.py @@ -329,7 +329,7 @@ async def execute( Error( name="WebSocketError", value="Failed to send execution request due to connection error", - traceback=str(e), + traceback="", ) ) await execution.queue.put(UnexpectedEndOfExecution()) From 467d8b16ea8dcacf1bd278e9ca11feb1a60e5588 Mon Sep 17 00:00:00 2001 From: Jakub Novak Date: Mon, 22 Sep 2025 13:10:10 +0200 Subject: [PATCH 05/23] Add reconnect logic --- template/server/messaging.py | 63 +++++++++++++++++++++++------------- 1 file changed, 41 insertions(+), 22 deletions(-) diff --git a/template/server/messaging.py b/template/server/messaging.py index 85ee947..6c76433 100644 --- a/template/server/messaging.py +++ b/template/server/messaging.py @@ -12,7 +12,10 @@ ) from pydantic import StrictStr from websockets.client import WebSocketClientProtocol, connect -from websockets.exceptions import ConnectionClosedError, WebSocketException +from websockets.exceptions import ( + ConnectionClosedError, + WebSocketException, +) from api.models.error import Error from api.models.logs import Stdout, Stderr @@ -62,6 +65,23 @@ def __init__(self, context_id: str, session_id: str, language: str, cwd: str): self._executions: Dict[str, Execution] = {} self._lock = asyncio.Lock() + async def reconnect(self): + # The results can be already lost + for execution in self._executions.values(): + await execution.queue.put( + Error( + name="WebSocketError", + value="Failed to send execution request due to unknown error", + traceback="", + ) + ) + await execution.queue.put(UnexpectedEndOfExecution()) + + if self._ws is not None: + await self._ws.close(reason="Reconnecting") + + await self.connect() + async def connect(self): logger.debug(f"WebSocket connecting to {self.url}") @@ -70,6 +90,7 @@ async def connect(self): self._ws = await connect( self.url, + ping_timeout=30, max_size=None, max_queue=None, logger=ws_logger, @@ -275,10 +296,6 @@ async def execute( env_vars: Dict[StrictStr, str], access_token: str, ): - message_id = str(uuid.uuid4()) - execution = Execution() - self._executions[message_id] = execution - if self._ws is None: raise Exception("WebSocket not connected") @@ -315,25 +332,26 @@ async def execute( ) complete_code = f"{indented_env_code}\n{complete_code}" - logger.info( - f"Sending code for the execution ({message_id}): {complete_code}" - ) - request = self._get_execute_request(message_id, complete_code, False) - # Send the code for execution - try: - await self._ws.send(request) - except (ConnectionClosedError, WebSocketException) as e: - logger.error(f"Failed to send execution request: {e}") - await execution.queue.put( - Error( - name="WebSocketError", - value="Failed to send execution request due to connection error", - traceback="", + for i in range(3): + try: + message_id = str(uuid.uuid4()) + execution = Execution() + self._executions[message_id] = execution + logger.info( + f"Sending code for the execution ({message_id}): {complete_code}" ) - ) - await execution.queue.put(UnexpectedEndOfExecution()) - except: # noqa: E722 + request = self._get_execute_request( + message_id, complete_code, False + ) + await self._ws.send(request) + break + except (ConnectionClosedError, WebSocketException) as e: + logger.warning( + f"WebSocket connection lost while sending execution request, {i+1}. reconnecting...: {str(e)}" + ) + await self.reconnect() + else: logger.error("Failed to send execution request due to unknown error") await execution.queue.put( Error( @@ -366,6 +384,7 @@ async def _receive_message(self): await self._process_message(json.loads(message)) except Exception as e: logger.error(f"WebSocket received error while receiving messages: {str(e)}") + await self.reconnect() async def _process_message(self, data: dict): """ From 1e9362f55bfb85269a55a812c1819d35f46013df Mon Sep 17 00:00:00 2001 From: Jakub Novak Date: Mon, 22 Sep 2025 13:10:21 +0200 Subject: [PATCH 06/23] Fix headers for unsecure sandbox --- .../e2b_code_interpreter/code_interpreter_async.py | 12 ++++++++++-- python/e2b_code_interpreter/code_interpreter_sync.py | 12 ++++++++++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/python/e2b_code_interpreter/code_interpreter_async.py b/python/e2b_code_interpreter/code_interpreter_async.py index 02c3e99..b316c59 100644 --- a/python/e2b_code_interpreter/code_interpreter_async.py +++ b/python/e2b_code_interpreter/code_interpreter_async.py @@ -191,6 +191,10 @@ async def run_code( request_timeout = request_timeout or self.connection_config.request_timeout context_id = context.id if context else None + headers = {} + if self._envd_access_token: + headers = {"X-Access-Token": self._envd_access_token} + try: async with self._client.stream( "POST", @@ -201,7 +205,7 @@ async def run_code( "language": language, "env_vars": envs, }, - headers={"X-Access-Token": self._envd_access_token}, + headers=headers, timeout=(request_timeout, timeout, request_timeout, request_timeout), ) as response: err = await aextract_exception(response) @@ -249,10 +253,14 @@ async def create_code_context( if cwd: data["cwd"] = cwd + headers = {} + if self._envd_access_token: + headers = {"X-Access-Token": self._envd_access_token} + try: response = await self._client.post( f"{self._jupyter_url}/contexts", - headers={"X-Access-Token": self._envd_access_token}, + headers=headers, json=data, timeout=request_timeout or self.connection_config.request_timeout, ) diff --git a/python/e2b_code_interpreter/code_interpreter_sync.py b/python/e2b_code_interpreter/code_interpreter_sync.py index 978c6dc..a7ada58 100644 --- a/python/e2b_code_interpreter/code_interpreter_sync.py +++ b/python/e2b_code_interpreter/code_interpreter_sync.py @@ -188,6 +188,10 @@ def run_code( request_timeout = request_timeout or self.connection_config.request_timeout context_id = context.id if context else None + headers = {} + if self._envd_access_token: + headers = {"X-Access-Token": self._envd_access_token or ""} + try: with self._client.stream( "POST", @@ -198,7 +202,7 @@ def run_code( "language": language, "env_vars": envs, }, - headers={"X-Access-Token": self._envd_access_token}, + headers=headers, timeout=(request_timeout, timeout, request_timeout, request_timeout), ) as response: err = extract_exception(response) @@ -246,11 +250,15 @@ def create_code_context( if cwd: data["cwd"] = cwd + headers = {} + if self._envd_access_token: + headers = {"X-Access-Token": self._envd_access_token or ""} + try: response = self._client.post( f"{self._jupyter_url}/contexts", json=data, - headers={"X-Access-Token": self._envd_access_token}, + headers=headers, timeout=request_timeout or self.connection_config.request_timeout, ) From 66a8d48fcb4271f9d00fa3cc1129f7cf5449abd9 Mon Sep 17 00:00:00 2001 From: Jakub Novak Date: Mon, 22 Sep 2025 13:59:50 +0200 Subject: [PATCH 07/23] Update the error message --- template/server/messaging.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/template/server/messaging.py b/template/server/messaging.py index 6c76433..c4011da 100644 --- a/template/server/messaging.py +++ b/template/server/messaging.py @@ -71,7 +71,7 @@ async def reconnect(self): await execution.queue.put( Error( name="WebSocketError", - value="Failed to send execution request due to unknown error", + value="The connections was lost, rerun the code to get the results", traceback="", ) ) From a2c1283e2f206e64d64d4e40ddd137df6b634372 Mon Sep 17 00:00:00 2001 From: Jakub Novak Date: Mon, 22 Sep 2025 14:03:56 +0200 Subject: [PATCH 08/23] Lint --- template/server/messaging.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/template/server/messaging.py b/template/server/messaging.py index c4011da..85358c7 100644 --- a/template/server/messaging.py +++ b/template/server/messaging.py @@ -348,7 +348,7 @@ async def execute( break except (ConnectionClosedError, WebSocketException) as e: logger.warning( - f"WebSocket connection lost while sending execution request, {i+1}. reconnecting...: {str(e)}" + f"WebSocket connection lost while sending execution request, {i + 1}. reconnecting...: {str(e)}" ) await self.reconnect() else: From 1950089d415d00b0eb7a5a89c6c1d6db0dd688dd Mon Sep 17 00:00:00 2001 From: Jakub Novak Date: Mon, 22 Sep 2025 14:23:35 +0200 Subject: [PATCH 09/23] Clean up --- template/server/messaging.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/template/server/messaging.py b/template/server/messaging.py index 85358c7..de91bf9 100644 --- a/template/server/messaging.py +++ b/template/server/messaging.py @@ -67,7 +67,7 @@ def __init__(self, context_id: str, session_id: str, language: str, cwd: str): async def reconnect(self): # The results can be already lost - for execution in self._executions.values(): + for key, execution in self._executions.items(): await execution.queue.put( Error( name="WebSocketError", @@ -332,12 +332,14 @@ async def execute( ) complete_code = f"{indented_env_code}\n{complete_code}" + message_id = str(uuid.uuid4()) + execution = Execution() + self._executions[message_id] = execution + + max_retries = 3 # Send the code for execution - for i in range(3): + for i in range(max_retries): try: - message_id = str(uuid.uuid4()) - execution = Execution() - self._executions[message_id] = execution logger.info( f"Sending code for the execution ({message_id}): {complete_code}" ) @@ -351,6 +353,13 @@ async def execute( f"WebSocket connection lost while sending execution request, {i + 1}. reconnecting...: {str(e)}" ) await self.reconnect() + + # Keep the last result, even if error + if i < max_retries - 1: + del self._executions[message_id] + message_id = str(uuid.uuid4()) + execution = Execution() + self._executions[message_id] = execution else: logger.error("Failed to send execution request due to unknown error") await execution.queue.put( From a2e6a5a20e383e78a72f76bafaa080c5ddbe12bf Mon Sep 17 00:00:00 2001 From: Jakub Novak Date: Mon, 22 Sep 2025 14:28:56 +0200 Subject: [PATCH 10/23] Don't reconnect in the last iteration --- template/server/messaging.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/template/server/messaging.py b/template/server/messaging.py index de91bf9..9d77405 100644 --- a/template/server/messaging.py +++ b/template/server/messaging.py @@ -349,13 +349,13 @@ async def execute( await self._ws.send(request) break except (ConnectionClosedError, WebSocketException) as e: - logger.warning( - f"WebSocket connection lost while sending execution request, {i + 1}. reconnecting...: {str(e)}" - ) - await self.reconnect() - # Keep the last result, even if error if i < max_retries - 1: + logger.warning( + f"WebSocket connection lost while sending execution request, {i + 1}. reconnecting...: {str(e)}" + ) + await self.reconnect() + del self._executions[message_id] message_id = str(uuid.uuid4()) execution = Execution() From fb85fc2957d74d15c3e4d5e1247e085ab67194c2 Mon Sep 17 00:00:00 2001 From: Jakub Novak Date: Mon, 22 Sep 2025 14:29:49 +0200 Subject: [PATCH 11/23] Change the error log --- template/server/messaging.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/template/server/messaging.py b/template/server/messaging.py index 9d77405..2461de8 100644 --- a/template/server/messaging.py +++ b/template/server/messaging.py @@ -361,11 +361,11 @@ async def execute( execution = Execution() self._executions[message_id] = execution else: - logger.error("Failed to send execution request due to unknown error") + logger.error("Failed to send execution request") await execution.queue.put( Error( name="WebSocketError", - value="Failed to send execution request due to unknown error", + value="Failed to send execution request", traceback="", ) ) From 175212125fc6dd0f9e5b53ce75173990b4d9111a Mon Sep 17 00:00:00 2001 From: Jakub Novak Date: Tue, 23 Sep 2025 11:58:37 +0200 Subject: [PATCH 12/23] Don't reconnect in the receive task --- template/server/messaging.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/template/server/messaging.py b/template/server/messaging.py index 2461de8..1322e51 100644 --- a/template/server/messaging.py +++ b/template/server/messaging.py @@ -393,7 +393,17 @@ async def _receive_message(self): await self._process_message(json.loads(message)) except Exception as e: logger.error(f"WebSocket received error while receiving messages: {str(e)}") - await self.reconnect() + finally: + # To prevent infinite hang, we need to cancel all ongoing execution as we could lost results during the reconnect + for key, execution in self._executions.items(): + await execution.queue.put( + Error( + name="WebSocketError", + value="The connections was lost, rerun the code to get the results", + traceback="", + ) + ) + await execution.queue.put(UnexpectedEndOfExecution()) async def _process_message(self, data: dict): """ From ed356888e2b85aad574137da2cdbf3cf78966563 Mon Sep 17 00:00:00 2001 From: Jakub Novak Date: Tue, 23 Sep 2025 12:20:59 +0200 Subject: [PATCH 13/23] Wait till the receive task doesn't finish --- template/server/messaging.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/template/server/messaging.py b/template/server/messaging.py index 1322e51..baa65df 100644 --- a/template/server/messaging.py +++ b/template/server/messaging.py @@ -80,6 +80,9 @@ async def reconnect(self): if self._ws is not None: await self._ws.close(reason="Reconnecting") + if self._receive_task is not None: + await self._receive_task + await self.connect() async def connect(self): @@ -90,7 +93,8 @@ async def connect(self): self._ws = await connect( self.url, - ping_timeout=30, + ping_timeout=0.03, + ping_interval=0.03, max_size=None, max_queue=None, logger=ws_logger, From 80f42c24e7f8c7a5e430a0532850f204a8e31bb5 Mon Sep 17 00:00:00 2001 From: Jakub Novak Date: Tue, 23 Sep 2025 13:43:16 +0200 Subject: [PATCH 14/23] Revert the interval --- template/server/messaging.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/template/server/messaging.py b/template/server/messaging.py index baa65df..96ee372 100644 --- a/template/server/messaging.py +++ b/template/server/messaging.py @@ -93,8 +93,7 @@ async def connect(self): self._ws = await connect( self.url, - ping_timeout=0.03, - ping_interval=0.03, + ping_timeout=30, max_size=None, max_queue=None, logger=ws_logger, From a8643147f5c92c5ea9a27343afa0da0e7fb7a5e8 Mon Sep 17 00:00:00 2001 From: Jakub Novak Date: Tue, 23 Sep 2025 13:46:35 +0200 Subject: [PATCH 15/23] Simplify --- template/server/messaging.py | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/template/server/messaging.py b/template/server/messaging.py index 96ee372..944be7b 100644 --- a/template/server/messaging.py +++ b/template/server/messaging.py @@ -66,17 +66,6 @@ def __init__(self, context_id: str, session_id: str, language: str, cwd: str): self._lock = asyncio.Lock() async def reconnect(self): - # The results can be already lost - for key, execution in self._executions.items(): - await execution.queue.put( - Error( - name="WebSocketError", - value="The connections was lost, rerun the code to get the results", - traceback="", - ) - ) - await execution.queue.put(UnexpectedEndOfExecution()) - if self._ws is not None: await self._ws.close(reason="Reconnecting") From c154f88f8ff7c7ff3626d2fc642d9efb7ba18c41 Mon Sep 17 00:00:00 2001 From: Jakub Novak Date: Fri, 26 Sep 2025 15:26:01 +0200 Subject: [PATCH 16/23] Address PR comments --- template/server/messaging.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/template/server/messaging.py b/template/server/messaging.py index 944be7b..adfa9d9 100644 --- a/template/server/messaging.py +++ b/template/server/messaging.py @@ -31,6 +31,9 @@ logger = logging.getLogger(__name__) +MAX_RECONNECT_RETRIES = 1 +PING_TIMEOUT = 30 + class Execution: def __init__(self, in_background: bool = False): @@ -82,7 +85,7 @@ async def connect(self): self._ws = await connect( self.url, - ping_timeout=30, + ping_timeout=PING_TIMEOUT, max_size=None, max_queue=None, logger=ws_logger, @@ -328,9 +331,9 @@ async def execute( execution = Execution() self._executions[message_id] = execution - max_retries = 3 # Send the code for execution - for i in range(max_retries): + # Initial request and retries + for i in range(1 + MAX_RECONNECT_RETRIES): try: logger.info( f"Sending code for the execution ({message_id}): {complete_code}" @@ -342,17 +345,13 @@ async def execute( break except (ConnectionClosedError, WebSocketException) as e: # Keep the last result, even if error - if i < max_retries - 1: + if i < MAX_RECONNECT_RETRIES - 1: logger.warning( f"WebSocket connection lost while sending execution request, {i + 1}. reconnecting...: {str(e)}" ) await self.reconnect() - - del self._executions[message_id] - message_id = str(uuid.uuid4()) - execution = Execution() - self._executions[message_id] = execution else: + # The retry didn't help, request wasn't sent successfully logger.error("Failed to send execution request") await execution.queue.put( Error( @@ -387,6 +386,7 @@ async def _receive_message(self): logger.error(f"WebSocket received error while receiving messages: {str(e)}") finally: # To prevent infinite hang, we need to cancel all ongoing execution as we could lost results during the reconnect + # Thanks to the locking, there can be either no ongoing execution or just one. for key, execution in self._executions.items(): await execution.queue.put( Error( From e7104023abe42d281809501a27b61998df8806a8 Mon Sep 17 00:00:00 2001 From: Jakub Novak Date: Fri, 26 Sep 2025 15:31:16 +0200 Subject: [PATCH 17/23] Increase the retries --- template/server/messaging.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/template/server/messaging.py b/template/server/messaging.py index adfa9d9..31c00b0 100644 --- a/template/server/messaging.py +++ b/template/server/messaging.py @@ -31,7 +31,7 @@ logger = logging.getLogger(__name__) -MAX_RECONNECT_RETRIES = 1 +MAX_RECONNECT_RETRIES = 3 PING_TIMEOUT = 30 From cecb2e6aa81620c7d9ea55a80d4908136d213527 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Nov=C3=A1k?= Date: Fri, 26 Sep 2025 06:35:52 -0700 Subject: [PATCH 18/23] Update template/server/messaging.py Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com> --- template/server/messaging.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/template/server/messaging.py b/template/server/messaging.py index 31c00b0..0b151f8 100644 --- a/template/server/messaging.py +++ b/template/server/messaging.py @@ -345,7 +345,7 @@ async def execute( break except (ConnectionClosedError, WebSocketException) as e: # Keep the last result, even if error - if i < MAX_RECONNECT_RETRIES - 1: + if i < MAX_RECONNECT_RETRIES: logger.warning( f"WebSocket connection lost while sending execution request, {i + 1}. reconnecting...: {str(e)}" ) From 8818ce77e37d10b2324618efc0a83c6ee42a28d3 Mon Sep 17 00:00:00 2001 From: Jakub Novak Date: Mon, 29 Sep 2025 13:43:08 +0200 Subject: [PATCH 19/23] Disable timeout completely --- template/server/messaging.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/template/server/messaging.py b/template/server/messaging.py index 0b151f8..1ba9a6a 100644 --- a/template/server/messaging.py +++ b/template/server/messaging.py @@ -32,7 +32,7 @@ logger = logging.getLogger(__name__) MAX_RECONNECT_RETRIES = 3 -PING_TIMEOUT = 30 +PING_TIMEOUT = None class Execution: From c012f3ca13e9bfdfb2bbf6de6e197bc3e242ac68 Mon Sep 17 00:00:00 2001 From: Jakub Novak Date: Tue, 7 Oct 2025 15:57:40 +0200 Subject: [PATCH 20/23] Fix missing access token --- python/e2b_code_interpreter/code_interpreter_async.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/e2b_code_interpreter/code_interpreter_async.py b/python/e2b_code_interpreter/code_interpreter_async.py index b316c59..a243b57 100644 --- a/python/e2b_code_interpreter/code_interpreter_async.py +++ b/python/e2b_code_interpreter/code_interpreter_async.py @@ -193,7 +193,7 @@ async def run_code( headers = {} if self._envd_access_token: - headers = {"X-Access-Token": self._envd_access_token} + headers = {"X-Access-Token": self._envd_access_token or ""} try: async with self._client.stream( @@ -255,7 +255,7 @@ async def create_code_context( headers = {} if self._envd_access_token: - headers = {"X-Access-Token": self._envd_access_token} + headers = {"X-Access-Token": self._envd_access_token or ""} try: response = await self._client.post( From 989e36fad31113e4b15ef8c32ff4ea8cbb85d8b4 Mon Sep 17 00:00:00 2001 From: Jakub Novak Date: Tue, 7 Oct 2025 17:24:27 +0200 Subject: [PATCH 21/23] Simplify --- python/e2b_code_interpreter/code_interpreter_async.py | 8 ++++---- python/e2b_code_interpreter/code_interpreter_sync.py | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/python/e2b_code_interpreter/code_interpreter_async.py b/python/e2b_code_interpreter/code_interpreter_async.py index a243b57..b812935 100644 --- a/python/e2b_code_interpreter/code_interpreter_async.py +++ b/python/e2b_code_interpreter/code_interpreter_async.py @@ -191,9 +191,9 @@ async def run_code( request_timeout = request_timeout or self.connection_config.request_timeout context_id = context.id if context else None - headers = {} + headers: Dict[str, str] = {} if self._envd_access_token: - headers = {"X-Access-Token": self._envd_access_token or ""} + headers = {"X-Access-Token": self._envd_access_token} try: async with self._client.stream( @@ -253,9 +253,9 @@ async def create_code_context( if cwd: data["cwd"] = cwd - headers = {} + headers: Dict[str, str] = {} if self._envd_access_token: - headers = {"X-Access-Token": self._envd_access_token or ""} + headers = {"X-Access-Token": self._envd_access_token} try: response = await self._client.post( diff --git a/python/e2b_code_interpreter/code_interpreter_sync.py b/python/e2b_code_interpreter/code_interpreter_sync.py index a7ada58..6cf56c1 100644 --- a/python/e2b_code_interpreter/code_interpreter_sync.py +++ b/python/e2b_code_interpreter/code_interpreter_sync.py @@ -188,9 +188,9 @@ def run_code( request_timeout = request_timeout or self.connection_config.request_timeout context_id = context.id if context else None - headers = {} + headers: Dict[str, str] = {} if self._envd_access_token: - headers = {"X-Access-Token": self._envd_access_token or ""} + headers = {"X-Access-Token": self._envd_access_token} try: with self._client.stream( @@ -250,9 +250,9 @@ def create_code_context( if cwd: data["cwd"] = cwd - headers = {} + headers: Dict[str, str] = {} if self._envd_access_token: - headers = {"X-Access-Token": self._envd_access_token or ""} + headers = {"X-Access-Token": self._envd_access_token} try: response = self._client.post( From 1a63a96ac328bedaec9b480cbb6bee8482199a91 Mon Sep 17 00:00:00 2001 From: Jakub Novak Date: Tue, 7 Oct 2025 17:26:20 +0200 Subject: [PATCH 22/23] Add changeset --- .changeset/curly-pumpkins-kick.md | 5 +++++ .changeset/wicked-mirrors-punch.md | 5 +++++ 2 files changed, 10 insertions(+) create mode 100644 .changeset/curly-pumpkins-kick.md create mode 100644 .changeset/wicked-mirrors-punch.md diff --git a/.changeset/curly-pumpkins-kick.md b/.changeset/curly-pumpkins-kick.md new file mode 100644 index 0000000..f8b47d5 --- /dev/null +++ b/.changeset/curly-pumpkins-kick.md @@ -0,0 +1,5 @@ +--- +'@e2b/code-interpreter-template': patch +--- + +Add retry diff --git a/.changeset/wicked-mirrors-punch.md b/.changeset/wicked-mirrors-punch.md new file mode 100644 index 0000000..2050d45 --- /dev/null +++ b/.changeset/wicked-mirrors-punch.md @@ -0,0 +1,5 @@ +--- +'@e2b/code-interpreter-python': patch +--- + +Fix issue with secure False From e51313b12764fedbd9379fb8f7d203070a6502d3 Mon Sep 17 00:00:00 2001 From: Jakub Novak Date: Tue, 7 Oct 2025 17:37:26 +0200 Subject: [PATCH 23/23] Revert unwanted change --- template/server/messaging.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/template/server/messaging.py b/template/server/messaging.py index 1ba9a6a..0b151f8 100644 --- a/template/server/messaging.py +++ b/template/server/messaging.py @@ -32,7 +32,7 @@ logger = logging.getLogger(__name__) MAX_RECONNECT_RETRIES = 3 -PING_TIMEOUT = None +PING_TIMEOUT = 30 class Execution: