1- import datetime
2- import math
3- from ipaddress import ip_address
41from typing import Literal
52
63from pydantic import BaseModel , ConfigDict , Field
96from rock .actions .sandbox .response import State , StateTransitionRecord
107from rock .actions .sandbox .sandbox_info import SandboxInfo
118from rock .admin .proto .request import TaskSetSpec
12- from rock .common .constants import E2B_CLIENT_ID , E2B_ENVD_VERSION , E2B_SANDBOX_IP_METADATA_KEY , E2B_STATE_BY_ROCK_STATE
139from rock .sandbox .utils .timeout import SandboxTimeoutHelper
14- from rock .sdk .common .exceptions import E2BSandboxNotFoundError
15- from rock .utils .format import parse_size_to_bytes
1610
1711
1812class E2BCreateSandboxResponse (BaseModel ):
@@ -22,6 +16,14 @@ class E2BCreateSandboxResponse(BaseModel):
2216 template_id : str = Field (alias = "templateID" )
2317
2418
19+ class E2BListedSandbox (BaseModel ):
20+ model_config = ConfigDict (populate_by_name = True )
21+
22+ sandbox_id : str = Field (alias = "sandboxID" )
23+ metadata : dict [str , str ]
24+ state : Literal ["running" , "paused" ]
25+
26+
2527class SandboxStartResponse (SandboxResponse ):
2628 sandbox_id : str | None = None
2729 host_name : str | None = None
@@ -115,68 +117,6 @@ class E2BSandboxDetail(BaseModel):
115117 started_at : str = Field (alias = "startedAt" )
116118 end_at : str = Field (alias = "endAt" )
117119
118- @staticmethod
119- def _state (sandbox_id : str , state : State | str | None ) -> Literal ["running" , "paused" ]:
120- try :
121- rock_state = state if isinstance (state , State ) else State (state )
122- return E2B_STATE_BY_ROCK_STATE [rock_state .value ]
123- except (KeyError , TypeError , ValueError ):
124- raise E2BSandboxNotFoundError (f"Sandbox { sandbox_id } not found" ) from None
125-
126- @staticmethod
127- def _iso8601_timestamp (sandbox_id : str , field : str , value : object ) -> str :
128- if not isinstance (value , str ):
129- raise ValueError (f"Sandbox { sandbox_id } { field } is invalid" )
130- try :
131- parsed = datetime .datetime .fromisoformat (value .replace ("Z" , "+00:00" ))
132- except ValueError :
133- raise ValueError (f"Sandbox { sandbox_id } { field } is invalid" ) from None
134- if parsed .tzinfo is None :
135- raise ValueError (f"Sandbox { sandbox_id } { field } must include a timezone" )
136- return parsed .isoformat (timespec = "seconds" )
137-
138- @classmethod
139- def from_sandbox_status (
140- cls ,
141- sandbox_id : str ,
142- sandbox_status : SandboxStatusResponse ,
143- ) -> "E2BSandboxDetail" :
144- state = cls ._state (sandbox_id , sandbox_status .state )
145- end_at = (
146- sandbox_status .auto_stop_time
147- if state == "running"
148- else sandbox_status .auto_delete_time or sandbox_status .archive_time
149- )
150-
151- metadata = sandbox_status .metadata
152- if not isinstance (metadata , dict ) or not all (
153- isinstance (key , str ) and isinstance (value , str ) for key , value in metadata .items ()
154- ):
155- raise ValueError (f"Sandbox { sandbox_id } metadata is invalid" )
156-
157- host_ip = sandbox_status .host_ip
158- if not isinstance (host_ip , str ) or not host_ip .strip ():
159- raise ValueError (f"Sandbox { sandbox_id } IP is missing" )
160- ip_address (host_ip )
161-
162- return cls (
163- sandboxID = sandbox_id ,
164- metadata = {** metadata , E2B_SANDBOX_IP_METADATA_KEY : host_ip },
165- state = state ,
166- clientID = E2B_CLIENT_ID ,
167- templateID = str (sandbox_status .image ),
168- envdVersion = E2B_ENVD_VERSION ,
169- cpuCount = max (1 , math .ceil (float (sandbox_status .cpus ))),
170- memoryMB = parse_size_to_bytes (str (sandbox_status .memory )) // (1024 ** 2 ),
171- diskSizeMB = parse_size_to_bytes (str (sandbox_status .disk )) // (1024 ** 2 ),
172- startedAt = cls ._iso8601_timestamp (
173- sandbox_id ,
174- "start time" ,
175- sandbox_status .start_time or sandbox_status .create_time ,
176- ),
177- endAt = cls ._iso8601_timestamp (sandbox_id , "end time" , end_at ),
178- )
179-
180120
181121class SandboxListStatusResponse (SandboxStatusResponse ):
182122 rock_authorization_encrypted : str | None = None
0 commit comments