blaxel 0.2.31__py3-none-any.whl → 0.2.31rc120__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. blaxel/__init__.py +3 -3
  2. blaxel/core/agents/__init__.py +6 -13
  3. blaxel/core/authentication/__init__.py +1 -2
  4. blaxel/core/authentication/devicemode.py +1 -9
  5. blaxel/core/authentication/oauth.py +6 -13
  6. blaxel/core/authentication/types.py +0 -1
  7. blaxel/core/cache/cache.py +3 -10
  8. blaxel/core/client/api/agents/list_agent_revisions.py +1 -3
  9. blaxel/core/client/api/compute/delete_sandbox_preview_token.py +2 -6
  10. blaxel/core/client/api/compute/start_sandbox.py +1 -3
  11. blaxel/core/client/api/compute/stop_sandbox.py +1 -3
  12. blaxel/core/client/api/default/list_sandbox_hub_definitions.py +2 -6
  13. blaxel/core/client/api/functions/list_function_revisions.py +1 -3
  14. blaxel/core/client/api/images/cleanup_images.py +1 -3
  15. blaxel/core/client/api/integrations/list_integration_connections.py +2 -6
  16. blaxel/core/client/api/invitations/list_all_pending_invitations.py +1 -3
  17. blaxel/core/client/api/jobs/create_job_execution.py +1 -3
  18. blaxel/core/client/api/jobs/delete_job_execution.py +1 -3
  19. blaxel/core/client/api/jobs/get_job_execution.py +1 -3
  20. blaxel/core/client/api/jobs/list_job_executions.py +2 -6
  21. blaxel/core/client/api/jobs/list_job_revisions.py +1 -3
  22. blaxel/core/client/api/locations/list_locations.py +1 -3
  23. blaxel/core/client/api/models/list_model_revisions.py +1 -3
  24. blaxel/core/client/api/service_accounts/create_workspace_service_account.py +2 -6
  25. blaxel/core/client/api/service_accounts/delete_workspace_service_account.py +2 -6
  26. blaxel/core/client/api/service_accounts/get_workspace_service_accounts.py +1 -3
  27. blaxel/core/client/api/service_accounts/update_workspace_service_account.py +2 -6
  28. blaxel/core/client/api/volume_templates/list_volume_templates.py +1 -3
  29. blaxel/core/client/api/workspaces/accept_workspace_invitation.py +2 -6
  30. blaxel/core/client/api/workspaces/invite_workspace_user.py +2 -6
  31. blaxel/core/client/api/workspaces/update_workspace_user_role.py +2 -6
  32. blaxel/core/client/client.py +19 -5
  33. blaxel/core/client/models/agent.py +4 -11
  34. blaxel/core/client/models/agent_spec.py +5 -18
  35. blaxel/core/client/models/billable_time_metric.py +1 -0
  36. blaxel/core/client/models/configuration.py +1 -0
  37. blaxel/core/client/models/core_spec.py +3 -10
  38. blaxel/core/client/models/core_spec_configurations.py +1 -0
  39. blaxel/core/client/models/create_job_execution_request.py +1 -0
  40. blaxel/core/client/models/create_job_execution_response.py +1 -0
  41. blaxel/core/client/models/custom_domain.py +2 -5
  42. blaxel/core/client/models/custom_domain_metadata.py +1 -0
  43. blaxel/core/client/models/custom_domain_spec.py +2 -5
  44. blaxel/core/client/models/delete_volume_template_version_response_200.py +2 -5
  45. blaxel/core/client/models/entrypoint.py +1 -0
  46. blaxel/core/client/models/form.py +2 -5
  47. blaxel/core/client/models/function.py +4 -11
  48. blaxel/core/client/models/function_spec.py +4 -13
  49. blaxel/core/client/models/image.py +2 -5
  50. blaxel/core/client/models/image_spec.py +1 -0
  51. blaxel/core/client/models/integration.py +3 -10
  52. blaxel/core/client/models/integration_connection.py +2 -5
  53. blaxel/core/client/models/integration_connection_spec.py +1 -0
  54. blaxel/core/client/models/integration_endpoint.py +2 -5
  55. blaxel/core/client/models/integration_endpoints.py +2 -0
  56. blaxel/core/client/models/job.py +4 -11
  57. blaxel/core/client/models/job_execution.py +2 -5
  58. blaxel/core/client/models/job_execution_spec.py +1 -0
  59. blaxel/core/client/models/job_execution_task.py +2 -5
  60. blaxel/core/client/models/job_metrics.py +2 -5
  61. blaxel/core/client/models/job_spec.py +4 -13
  62. blaxel/core/client/models/jobs_network_chart.py +1 -0
  63. blaxel/core/client/models/jobs_success_failed_chart.py +3 -10
  64. blaxel/core/client/models/latency_metric.py +2 -5
  65. blaxel/core/client/models/location_response.py +1 -0
  66. blaxel/core/client/models/mcp_definition.py +2 -5
  67. blaxel/core/client/models/metadata.py +1 -0
  68. blaxel/core/client/models/metrics.py +4 -11
  69. blaxel/core/client/models/model.py +4 -11
  70. blaxel/core/client/models/model_spec.py +3 -10
  71. blaxel/core/client/models/pending_invitation_accept.py +2 -5
  72. blaxel/core/client/models/pending_invitation_render.py +3 -10
  73. blaxel/core/client/models/policy.py +2 -5
  74. blaxel/core/client/models/policy_spec.py +4 -11
  75. blaxel/core/client/models/preview.py +2 -5
  76. blaxel/core/client/models/preview_spec.py +1 -0
  77. blaxel/core/client/models/preview_token.py +2 -5
  78. blaxel/core/client/models/public_ips.py +1 -0
  79. blaxel/core/client/models/request_duration_over_time_metrics.py +1 -0
  80. blaxel/core/client/models/request_total_by_origin_metric.py +7 -16
  81. blaxel/core/client/models/request_total_metric.py +3 -8
  82. blaxel/core/client/models/resource_metrics.py +17 -58
  83. blaxel/core/client/models/runtime.py +1 -0
  84. blaxel/core/client/models/sandbox.py +4 -11
  85. blaxel/core/client/models/sandbox_definition.py +1 -0
  86. blaxel/core/client/models/sandbox_lifecycle.py +1 -0
  87. blaxel/core/client/models/sandbox_spec.py +6 -21
  88. blaxel/core/client/models/serverless_config.py +1 -0
  89. blaxel/core/client/models/start_sandbox.py +2 -5
  90. blaxel/core/client/models/stop_sandbox.py +2 -5
  91. blaxel/core/client/models/store_agent.py +1 -0
  92. blaxel/core/client/models/store_configuration.py +1 -0
  93. blaxel/core/client/models/template.py +1 -0
  94. blaxel/core/client/models/time_to_first_token_over_time_metrics.py +2 -3
  95. blaxel/core/client/models/token_rate_metrics.py +1 -0
  96. blaxel/core/client/models/trigger.py +1 -0
  97. blaxel/core/client/models/trigger_configuration.py +1 -0
  98. blaxel/core/client/models/volume.py +4 -11
  99. blaxel/core/client/models/volume_template.py +2 -5
  100. blaxel/core/client/models/workspace.py +2 -5
  101. blaxel/core/client/response_interceptor.py +1 -3
  102. blaxel/core/common/autoload.py +11 -9
  103. blaxel/core/common/env.py +8 -10
  104. blaxel/core/common/settings.py +2 -4
  105. blaxel/core/common/webhook.py +1 -0
  106. blaxel/core/jobs/__init__.py +3 -13
  107. blaxel/core/mcp/client.py +2 -8
  108. blaxel/core/mcp/server.py +2 -8
  109. blaxel/core/models/__init__.py +5 -6
  110. blaxel/core/sandbox/__init__.py +1 -1
  111. blaxel/core/sandbox/client/api/codegen/get_codegen_reranking_path.py +2 -6
  112. blaxel/core/sandbox/client/api/fastapply/put_codegen_fastapply_path.py +2 -6
  113. blaxel/core/sandbox/client/api/filesystem/delete_filesystem_multipart_upload_id_abort.py +2 -6
  114. blaxel/core/sandbox/client/api/filesystem/delete_filesystem_path.py +2 -6
  115. blaxel/core/sandbox/client/api/filesystem/delete_filesystem_tree_path.py +2 -6
  116. blaxel/core/sandbox/client/api/filesystem/get_filesystem_content_search_path.py +1 -3
  117. blaxel/core/sandbox/client/api/filesystem/get_filesystem_find_path.py +2 -6
  118. blaxel/core/sandbox/client/api/filesystem/get_filesystem_search_path.py +2 -6
  119. blaxel/core/sandbox/client/api/filesystem/get_watch_filesystem_path.py +2 -6
  120. blaxel/core/sandbox/client/api/filesystem/post_filesystem_multipart_upload_id_complete.py +2 -6
  121. blaxel/core/sandbox/client/api/filesystem/put_filesystem_path.py +2 -6
  122. blaxel/core/sandbox/client/api/process/delete_process_identifier.py +2 -6
  123. blaxel/core/sandbox/client/api/process/delete_process_identifier_kill.py +2 -6
  124. blaxel/core/sandbox/client/api/process/get_process.py +1 -3
  125. blaxel/core/sandbox/client/api/process/get_process_identifier.py +2 -6
  126. blaxel/core/sandbox/client/api/process/get_process_identifier_logs.py +2 -6
  127. blaxel/core/sandbox/client/api/process/get_process_identifier_logs_stream.py +2 -6
  128. blaxel/core/sandbox/client/api/process/post_process.py +2 -6
  129. blaxel/core/sandbox/client/client.py +1 -3
  130. blaxel/core/sandbox/client/models/filesystem_multipart_upload_parts.py +1 -3
  131. blaxel/core/sandbox/default/__init__.py +1 -0
  132. blaxel/core/sandbox/default/action.py +3 -3
  133. blaxel/core/sandbox/default/codegen.py +4 -2
  134. blaxel/core/sandbox/default/filesystem.py +82 -38
  135. blaxel/core/sandbox/default/interpreter.py +10 -17
  136. blaxel/core/sandbox/default/preview.py +2 -6
  137. blaxel/core/sandbox/default/process.py +7 -25
  138. blaxel/core/sandbox/default/sandbox.py +2 -7
  139. blaxel/core/sandbox/sync/__init__.py +2 -0
  140. blaxel/core/sandbox/sync/action.py +3 -2
  141. blaxel/core/sandbox/sync/codegen.py +5 -1
  142. blaxel/core/sandbox/sync/filesystem.py +6 -17
  143. blaxel/core/sandbox/sync/interpreter.py +6 -10
  144. blaxel/core/sandbox/sync/network.py +2 -0
  145. blaxel/core/sandbox/sync/preview.py +9 -21
  146. blaxel/core/sandbox/sync/process.py +8 -32
  147. blaxel/core/sandbox/sync/sandbox.py +6 -13
  148. blaxel/core/sandbox/sync/session.py +4 -6
  149. blaxel/core/sandbox/types.py +1 -2
  150. blaxel/core/tools/__init__.py +6 -30
  151. blaxel/core/tools/common.py +1 -1
  152. blaxel/core/tools/types.py +1 -2
  153. blaxel/crewai/model.py +5 -20
  154. blaxel/googleadk/__init__.py +1 -1
  155. blaxel/googleadk/tools.py +5 -3
  156. blaxel/langgraph/custom/gemini.py +133 -126
  157. blaxel/langgraph/model.py +50 -54
  158. blaxel/langgraph/tools.py +3 -9
  159. blaxel/llamaindex/custom/cohere.py +16 -25
  160. blaxel/llamaindex/model.py +57 -44
  161. blaxel/llamaindex/tools.py +3 -2
  162. blaxel/pydantic/custom/gemini.py +3 -3
  163. blaxel/pydantic/tools.py +4 -2
  164. blaxel/telemetry/exporters.py +3 -10
  165. blaxel/telemetry/instrumentation/blaxel_langgraph.py +2 -4
  166. blaxel/telemetry/instrumentation/blaxel_langgraph_gemini.py +5 -22
  167. blaxel/telemetry/instrumentation/utils.py +3 -3
  168. blaxel/telemetry/log/log.py +3 -2
  169. blaxel/telemetry/log/logger.py +15 -21
  170. blaxel/telemetry/span.py +6 -10
  171. {blaxel-0.2.31.dist-info → blaxel-0.2.31rc120.dist-info}/METADATA +2 -2
  172. {blaxel-0.2.31.dist-info → blaxel-0.2.31rc120.dist-info}/RECORD +174 -174
  173. {blaxel-0.2.31.dist-info → blaxel-0.2.31rc120.dist-info}/WHEEL +0 -0
  174. {blaxel-0.2.31.dist-info → blaxel-0.2.31rc120.dist-info}/licenses/LICENSE +0 -0
@@ -17,9 +17,7 @@ class CodeInterpreter(SandboxInstance):
17
17
  DEFAULT_PORTS = [
18
18
  {"name": "jupyter", "target": 8888, "protocol": "HTTP"},
19
19
  ]
20
- DEFAULT_LIFECYCLE = {
21
- "expirationPolicies": [{"type": "ttl-idle", "value": "30m", "action": "delete"}]
22
- }
20
+ DEFAULT_LIFECYCLE = {"expirationPolicies": [{"type": "ttl-idle", "value": "30m", "action": "delete"}]}
23
21
 
24
22
  @classmethod
25
23
  async def get(cls, sandbox_name: str) -> CodeInterpreter:
@@ -150,15 +148,11 @@ class CodeInterpreter(SandboxInstance):
150
148
  elif data_type == "stdout":
151
149
  execution.logs.stdout.append(data["text"])
152
150
  if on_stdout:
153
- return on_stdout(
154
- CodeInterpreter.OutputMessage(data["text"], data.get("timestamp"), False)
155
- )
151
+ return on_stdout(CodeInterpreter.OutputMessage(data["text"], data.get("timestamp"), False))
156
152
  elif data_type == "stderr":
157
153
  execution.logs.stderr.append(data["text"])
158
154
  if on_stderr:
159
- return on_stderr(
160
- CodeInterpreter.OutputMessage(data["text"], data.get("timestamp"), True)
161
- )
155
+ return on_stderr(CodeInterpreter.OutputMessage(data["text"], data.get("timestamp"), True))
162
156
  elif data_type == "error":
163
157
  execution.error = CodeInterpreter.ExecutionError(
164
158
  data.get("name", ""), data.get("value"), data.get("traceback")
@@ -206,10 +200,7 @@ class CodeInterpreter(SandboxInstance):
206
200
 
207
201
  client = self.process.get_client()
208
202
  timeout_cfg = httpx.Timeout(
209
- connect=connect_timeout,
210
- read=read_timeout,
211
- write=write_timeout,
212
- pool=pool_timeout,
203
+ connect=connect_timeout, read=read_timeout, write=write_timeout, pool=pool_timeout
213
204
  )
214
205
  async with client.stream(
215
206
  "POST",
@@ -252,7 +243,7 @@ class CodeInterpreter(SandboxInstance):
252
243
  on_error=on_error,
253
244
  )
254
245
  except json.JSONDecodeError:
255
- # Fallback: treat as stdout text-only message
246
+ # Fallback: treat as stdout text-only message
256
247
  execution.logs.stdout.append(decoded)
257
248
  if on_stdout:
258
249
  on_stdout(CodeInterpreter.OutputMessage(decoded, None, False))
@@ -280,10 +271,10 @@ class CodeInterpreter(SandboxInstance):
280
271
  try:
281
272
  # Always read response body first
282
273
  body_bytes = await response.aread()
283
-
274
+
284
275
  if response.status_code >= 400:
285
276
  try:
286
- body_text = body_bytes.decode("utf-8", errors="ignore")
277
+ body_text = body_bytes.decode('utf-8', errors='ignore')
287
278
  except Exception:
288
279
  body_text = "<unavailable>"
289
280
  method = getattr(response.request, "method", "UNKNOWN")
@@ -296,8 +287,10 @@ class CodeInterpreter(SandboxInstance):
296
287
  )
297
288
  self.logger.debug(details)
298
289
  raise RuntimeError(details)
299
-
290
+
300
291
  data = json.loads(body_bytes)
301
292
  return CodeInterpreter.Context.from_json(data)
302
293
  finally:
303
294
  await response.aclose()
295
+
296
+
@@ -15,15 +15,11 @@ from ...client.api.compute.delete_sandbox_preview import (
15
15
  from ...client.api.compute.delete_sandbox_preview_token import (
16
16
  asyncio as delete_sandbox_preview_token,
17
17
  )
18
- from ...client.api.compute.get_sandbox_preview import (
19
- asyncio as get_sandbox_preview,
20
- )
18
+ from ...client.api.compute.get_sandbox_preview import asyncio as get_sandbox_preview
21
19
  from ...client.api.compute.list_sandbox_preview_tokens import (
22
20
  asyncio as list_sandbox_preview_tokens,
23
21
  )
24
- from ...client.api.compute.list_sandbox_previews import (
25
- asyncio as list_sandbox_previews,
26
- )
22
+ from ...client.api.compute.list_sandbox_previews import asyncio as list_sandbox_previews
27
23
  from ...client.client import client
28
24
  from ...client.models import (
29
25
  Preview,
@@ -6,11 +6,7 @@ import httpx
6
6
  from ...common.settings import settings
7
7
  from ..client.models import ProcessResponse, SuccessResponse
8
8
  from ..client.models.process_request import ProcessRequest
9
- from ..types import (
10
- ProcessRequestWithLog,
11
- ProcessResponseWithLog,
12
- SandboxConfiguration,
13
- )
9
+ from ..types import ProcessRequestWithLog, ProcessResponseWithLog, SandboxConfiguration
14
10
  from .action import SandboxAction
15
11
 
16
12
 
@@ -19,9 +15,7 @@ class SandboxProcess(SandboxAction):
19
15
  super().__init__(sandbox_config)
20
16
 
21
17
  def stream_logs(
22
- self,
23
- process_name: str,
24
- options: Dict[str, Callable[[str], None]] | None = None,
18
+ self, process_name: str, options: Dict[str, Callable[[str], None]] | None = None
25
19
  ) -> Dict[str, Callable[[], None]]:
26
20
  """Stream logs from a process with automatic reconnection and deduplication."""
27
21
  if options is None:
@@ -117,9 +111,7 @@ class SandboxProcess(SandboxAction):
117
111
  return {"close": close}
118
112
 
119
113
  def _stream_logs(
120
- self,
121
- identifier: str,
122
- options: Dict[str, Callable[[str], None]] | None = None,
114
+ self, identifier: str, options: Dict[str, Callable[[str], None]] | None = None
123
115
  ) -> Dict[str, Callable[[], None]]:
124
116
  """Private method to stream logs from a process with callbacks for different output types."""
125
117
  if options is None:
@@ -183,8 +175,7 @@ class SandboxProcess(SandboxAction):
183
175
  return {"close": close}
184
176
 
185
177
  async def exec(
186
- self,
187
- process: Union[ProcessRequest, ProcessRequestWithLog, Dict[str, Any]],
178
+ self, process: Union[ProcessRequest, ProcessRequestWithLog, Dict[str, Any]]
188
179
  ) -> Union[ProcessResponse, ProcessResponseWithLog]:
189
180
  """Execute a process in the sandbox."""
190
181
  on_log = None
@@ -209,14 +200,13 @@ class SandboxProcess(SandboxAction):
209
200
  # Always start process without wait_for_completion to avoid server-side blocking
210
201
  if should_wait_for_completion and on_log is not None:
211
202
  process.wait_for_completion = False
212
-
203
+
213
204
  client = self.get_client()
214
205
  response = await client.post("/process", json=process.to_dict())
215
206
  try:
216
207
  content_bytes = await response.aread()
217
208
  self.handle_response_error(response)
218
209
  import json
219
-
220
210
  response_data = json.loads(content_bytes) if content_bytes else None
221
211
  result = ProcessResponse.from_dict(response_data)
222
212
  finally:
@@ -237,8 +227,7 @@ class SandboxProcess(SandboxAction):
237
227
  if on_log is not None:
238
228
  stream_control = self._stream_logs(result.pid, {"on_log": on_log})
239
229
  return ProcessResponseWithLog(
240
- result,
241
- lambda: stream_control["close"]() if stream_control else None,
230
+ result, lambda: stream_control["close"]() if stream_control else None
242
231
  )
243
232
 
244
233
  return result
@@ -266,7 +255,6 @@ class SandboxProcess(SandboxAction):
266
255
 
267
256
  async def get(self, identifier: str) -> ProcessResponse:
268
257
  import json
269
-
270
258
  client = self.get_client()
271
259
  response = await client.get(f"/process/{identifier}")
272
260
  try:
@@ -278,7 +266,6 @@ class SandboxProcess(SandboxAction):
278
266
 
279
267
  async def list(self) -> list[ProcessResponse]:
280
268
  import json
281
-
282
269
  client = self.get_client()
283
270
  response = await client.get("/process")
284
271
  try:
@@ -290,7 +277,6 @@ class SandboxProcess(SandboxAction):
290
277
 
291
278
  async def stop(self, identifier: str) -> SuccessResponse:
292
279
  import json
293
-
294
280
  client = self.get_client()
295
281
  response = await client.delete(f"/process/{identifier}")
296
282
  try:
@@ -302,7 +288,6 @@ class SandboxProcess(SandboxAction):
302
288
 
303
289
  async def kill(self, identifier: str) -> SuccessResponse:
304
290
  import json
305
-
306
291
  client = self.get_client()
307
292
  response = await client.delete(f"/process/{identifier}/kill")
308
293
  try:
@@ -313,12 +298,9 @@ class SandboxProcess(SandboxAction):
313
298
  await response.aclose()
314
299
 
315
300
  async def logs(
316
- self,
317
- identifier: str,
318
- log_type: Literal["stdout", "stderr", "all"] = "all",
301
+ self, identifier: str, log_type: Literal["stdout", "stderr", "all"] = "all"
319
302
  ) -> str:
320
303
  import json
321
-
322
304
  client = self.get_client()
323
305
  response = await client.get(f"/process/{identifier}/logs")
324
306
  try:
@@ -105,8 +105,7 @@ class SandboxInstance:
105
105
  or "expires" in (sandbox if isinstance(sandbox, dict) else sandbox.__dict__)
106
106
  or "region" in (sandbox if isinstance(sandbox, dict) else sandbox.__dict__)
107
107
  or "lifecycle" in (sandbox if isinstance(sandbox, dict) else sandbox.__dict__)
108
- or "snapshot_enabled"
109
- in (sandbox if isinstance(sandbox, dict) else sandbox.__dict__)
108
+ or "snapshot_enabled" in (sandbox if isinstance(sandbox, dict) else sandbox.__dict__)
110
109
  )
111
110
  )
112
111
  ):
@@ -133,11 +132,7 @@ class SandboxInstance:
133
132
  metadata=Metadata(name=name),
134
133
  spec=SandboxSpec(
135
134
  runtime=Runtime(
136
- image=image,
137
- memory=memory,
138
- ports=ports,
139
- envs=envs,
140
- generation="mk3",
135
+ image=image, memory=memory, ports=ports, envs=envs, generation="mk3"
141
136
  ),
142
137
  volumes=volumes,
143
138
  ),
@@ -15,3 +15,5 @@ __all__ = [
15
15
  "SyncSandboxCodegen",
16
16
  "SyncCodeInterpreter",
17
17
  ]
18
+
19
+
@@ -51,8 +51,7 @@ class SyncSandboxAction:
51
51
  def get_client(self) -> httpx.Client:
52
52
  if self.sandbox_config.force_url:
53
53
  return httpx.Client(
54
- base_url=self.sandbox_config.force_url,
55
- headers=self.sandbox_config.headers,
54
+ base_url=self.sandbox_config.force_url, headers=self.sandbox_config.headers
56
55
  )
57
56
  return httpx.Client(
58
57
  base_url=self.url,
@@ -62,3 +61,5 @@ class SyncSandboxAction:
62
61
  def handle_response_error(self, response: httpx.Response):
63
62
  if not response.is_success:
64
63
  raise ResponseError(response)
64
+
65
+
@@ -20,7 +20,9 @@ class SyncSandboxCodegen(SyncSandboxAction):
20
20
  def __init__(self, sandbox_config: SandboxConfiguration):
21
21
  super().__init__(sandbox_config)
22
22
 
23
- def fastapply(self, path: str, code_edit: str, model: str | None = None) -> ApplyEditResponse:
23
+ def fastapply(
24
+ self, path: str, code_edit: str, model: str | None = None
25
+ ) -> ApplyEditResponse:
24
26
  body = ApplyEditRequest(code_edit=code_edit, model=model)
25
27
  client = Client(
26
28
  base_url=self.url,
@@ -64,3 +66,5 @@ class SyncSandboxCodegen(SyncSandboxAction):
64
66
  if isinstance(response, ErrorResponse):
65
67
  raise Exception(f"Reranking failed: {response}")
66
68
  return response
69
+
70
+
@@ -61,11 +61,7 @@ class SyncSandboxFileSystem(SyncSandboxAction):
61
61
  return self._upload_with_multipart(path, content, "0644")
62
62
  binary_file = io.BytesIO(content)
63
63
  files = {
64
- "file": (
65
- "binary-file.bin",
66
- binary_file,
67
- "application/octet-stream",
68
- ),
64
+ "file": ("binary-file.bin", binary_file, "application/octet-stream"),
69
65
  }
70
66
  data = {"permissions": "0644", "path": path}
71
67
  url = f"{self.url}/filesystem/{path}"
@@ -199,10 +195,7 @@ class SyncSandboxFileSystem(SyncSandboxAction):
199
195
  name=file_event_data.get("name", ""),
200
196
  content=file_event_data.get("content"),
201
197
  )
202
- if options.get("with_content") and file_event.op in [
203
- "CREATE",
204
- "WRITE",
205
- ]:
198
+ if options.get("with_content") and file_event.op in ["CREATE", "WRITE"]:
206
199
  try:
207
200
  file_path = file_event.path
208
201
  if file_path.endswith("/"):
@@ -251,9 +244,7 @@ class SyncSandboxFileSystem(SyncSandboxAction):
251
244
  self.handle_response_error(response)
252
245
  return response.json()
253
246
 
254
- def _complete_multipart_upload(
255
- self, upload_id: str, parts: List[Dict[str, Any]]
256
- ) -> SuccessResponse:
247
+ def _complete_multipart_upload(self, upload_id: str, parts: List[Dict[str, Any]]) -> SuccessResponse:
257
248
  url = f"{self.url}/filesystem-multipart/{upload_id}/complete"
258
249
  headers = {**settings.headers, **self.sandbox_config.headers}
259
250
  body = {"parts": parts}
@@ -270,9 +261,7 @@ class SyncSandboxFileSystem(SyncSandboxAction):
270
261
  if not response.is_success:
271
262
  logger.warning(f"Failed to abort multipart upload: {response.status_code}")
272
263
 
273
- def _upload_with_multipart(
274
- self, path: str, data: bytes, permissions: str = "0644"
275
- ) -> SuccessResponse:
264
+ def _upload_with_multipart(self, path: str, data: bytes, permissions: str = "0644") -> SuccessResponse:
276
265
  init_response = self._initiate_multipart_upload(path, permissions)
277
266
  upload_id = init_response.get("uploadId")
278
267
  if not upload_id:
@@ -285,10 +274,8 @@ class SyncSandboxFileSystem(SyncSandboxAction):
285
274
  for i in range(0, num_parts, MAX_PARALLEL_UPLOADS):
286
275
  threads = []
287
276
  results: Dict[int, Dict[str, Any]] = {}
288
-
289
277
  def make_upload(part_number: int, chunk: bytes):
290
278
  results[part_number] = self._upload_part(upload_id, part_number, chunk)
291
-
292
279
  for j in range(MAX_PARALLEL_UPLOADS):
293
280
  if i + j >= num_parts:
294
281
  break
@@ -311,3 +298,5 @@ class SyncSandboxFileSystem(SyncSandboxAction):
311
298
  except Exception as abort_error:
312
299
  logger.warning(f"Failed to abort multipart upload: {abort_error}")
313
300
  raise error
301
+
302
+
@@ -15,9 +15,7 @@ class SyncCodeInterpreter(SyncSandboxInstance):
15
15
  DEFAULT_PORTS = [
16
16
  {"name": "jupyter", "target": 8888, "protocol": "HTTP"},
17
17
  ]
18
- DEFAULT_LIFECYCLE = {
19
- "expirationPolicies": [{"type": "ttl-idle", "value": "30m", "action": "delete"}]
20
- }
18
+ DEFAULT_LIFECYCLE = {"expirationPolicies": [{ "type": "ttl-idle", "value": "30m", "action": "delete" }]}
21
19
 
22
20
  @classmethod
23
21
  def get(cls, sandbox_name: str) -> "SyncCodeInterpreter":
@@ -223,10 +221,7 @@ class SyncCodeInterpreter(SyncSandboxInstance):
223
221
  # Use the process client to inherit base_url and headers
224
222
  with self.process.get_client() as client:
225
223
  timeout_cfg = httpx.Timeout(
226
- connect=connect_timeout,
227
- read=read_timeout,
228
- write=write_timeout,
229
- pool=pool_timeout,
224
+ connect=connect_timeout, read=read_timeout, write=write_timeout, pool=pool_timeout
230
225
  )
231
226
  with client.stream(
232
227
  "POST",
@@ -243,9 +238,7 @@ class SyncCodeInterpreter(SyncSandboxInstance):
243
238
  if not line:
244
239
  continue
245
240
  try:
246
- decoded = (
247
- line.decode() if isinstance(line, bytes | bytearray) else str(line)
248
- )
241
+ decoded = line.decode() if isinstance(line, bytes | bytearray) else str(line)
249
242
  except Exception:
250
243
  decoded = str(line)
251
244
  try:
@@ -277,6 +270,7 @@ class SyncCodeInterpreter(SyncSandboxInstance):
277
270
  if cwd:
278
271
  data["cwd"] = cwd
279
272
 
273
+
280
274
  with self.process.get_client() as client:
281
275
  response = client.post(
282
276
  "/port/8888/contexts",
@@ -289,3 +283,5 @@ class SyncCodeInterpreter(SyncSandboxInstance):
289
283
  raise RuntimeError(details)
290
284
  data = response.json()
291
285
  return SyncCodeInterpreter.Context.from_json(data)
286
+
287
+
@@ -7,3 +7,5 @@ class SyncSandboxNetwork(SyncSandboxAction):
7
7
  super().__init__(sandbox_config)
8
8
 
9
9
  # Placeholder for future sync network operations
10
+
11
+
@@ -3,27 +3,13 @@ from datetime import datetime
3
3
  from typing import Any, Dict, List, Union
4
4
 
5
5
  from ...client import errors
6
- from ...client.api.compute.create_sandbox_preview import (
7
- sync as create_sandbox_preview,
8
- )
9
- from ...client.api.compute.create_sandbox_preview_token import (
10
- sync as create_sandbox_preview_token,
11
- )
12
- from ...client.api.compute.delete_sandbox_preview import (
13
- sync as delete_sandbox_preview,
14
- )
15
- from ...client.api.compute.delete_sandbox_preview_token import (
16
- sync as delete_sandbox_preview_token,
17
- )
18
- from ...client.api.compute.get_sandbox_preview import (
19
- sync as get_sandbox_preview,
20
- )
21
- from ...client.api.compute.list_sandbox_preview_tokens import (
22
- sync as list_sandbox_preview_tokens,
23
- )
24
- from ...client.api.compute.list_sandbox_previews import (
25
- sync as list_sandbox_previews,
26
- )
6
+ from ...client.api.compute.create_sandbox_preview import sync as create_sandbox_preview
7
+ from ...client.api.compute.create_sandbox_preview_token import sync as create_sandbox_preview_token
8
+ from ...client.api.compute.delete_sandbox_preview import sync as delete_sandbox_preview
9
+ from ...client.api.compute.delete_sandbox_preview_token import sync as delete_sandbox_preview_token
10
+ from ...client.api.compute.get_sandbox_preview import sync as get_sandbox_preview
11
+ from ...client.api.compute.list_sandbox_preview_tokens import sync as list_sandbox_preview_tokens
12
+ from ...client.api.compute.list_sandbox_previews import sync as list_sandbox_previews
27
13
  from ...client.client import client
28
14
  from ...client.models import (
29
15
  Preview,
@@ -169,3 +155,5 @@ def to_utc_z(dt: datetime) -> str:
169
155
  elif "T" in iso_string and not iso_string.endswith("Z"):
170
156
  return iso_string + "Z"
171
157
  return iso_string
158
+
159
+
@@ -7,11 +7,7 @@ import httpx
7
7
  from ...common.settings import settings
8
8
  from ..client.models import ProcessResponse, SuccessResponse
9
9
  from ..client.models.process_request import ProcessRequest
10
- from ..types import (
11
- ProcessRequestWithLog,
12
- ProcessResponseWithLog,
13
- SandboxConfiguration,
14
- )
10
+ from ..types import ProcessRequestWithLog, ProcessResponseWithLog, SandboxConfiguration
15
11
  from .action import SyncSandboxAction
16
12
 
17
13
 
@@ -20,9 +16,7 @@ class SyncSandboxProcess(SyncSandboxAction):
20
16
  super().__init__(sandbox_config)
21
17
 
22
18
  def stream_logs(
23
- self,
24
- process_name: str,
25
- options: Dict[str, Callable[[str], None]] | None = None,
19
+ self, process_name: str, options: Dict[str, Callable[[str], None]] | None = None
26
20
  ) -> Dict[str, Callable[[], None]]:
27
21
  if options is None:
28
22
  options = {}
@@ -37,7 +31,6 @@ class SyncSandboxProcess(SyncSandboxAction):
37
31
  def start_stream():
38
32
  nonlocal current_close
39
33
  log_counter = [0]
40
-
41
34
  def make_dedup(cb_key: str):
42
35
  def inner(content: str):
43
36
  key = f"{log_counter[0]}:{content}"
@@ -46,9 +39,7 @@ class SyncSandboxProcess(SyncSandboxAction):
46
39
  seen_logs.add(key)
47
40
  if options.get(cb_key):
48
41
  options[cb_key](content)
49
-
50
42
  return inner
51
-
52
43
  wrapped_options: Dict[str, Callable[[str], None]] = {}
53
44
  if "on_log" in options:
54
45
  wrapped_options["on_log"] = make_dedup("on_log")
@@ -59,11 +50,9 @@ class SyncSandboxProcess(SyncSandboxAction):
59
50
  if current_close["fn"]:
60
51
  current_close["fn"]()
61
52
  current_close["fn"] = self._stream_logs(process_name, wrapped_options)["close"]
62
-
63
53
  def schedule():
64
54
  if is_running.is_set():
65
55
  start_stream()
66
-
67
56
  with timer_lock:
68
57
  if reconnect_timer["t"]:
69
58
  reconnect_timer["t"].cancel()
@@ -71,9 +60,7 @@ class SyncSandboxProcess(SyncSandboxAction):
71
60
  reconnect_timer["t"] = t
72
61
  t.daemon = True
73
62
  t.start()
74
-
75
63
  start_stream()
76
-
77
64
  def close():
78
65
  is_running.clear()
79
66
  with timer_lock:
@@ -84,18 +71,14 @@ class SyncSandboxProcess(SyncSandboxAction):
84
71
  current_close["fn"]()
85
72
  current_close["fn"] = None
86
73
  seen_logs.clear()
87
-
88
74
  return {"close": close}
89
75
 
90
76
  def _stream_logs(
91
- self,
92
- identifier: str,
93
- options: Dict[str, Callable[[str], None]] | None = None,
77
+ self, identifier: str, options: Dict[str, Callable[[str], None]] | None = None
94
78
  ) -> Dict[str, Callable[[], None]]:
95
79
  if options is None:
96
80
  options = {}
97
81
  closed = threading.Event()
98
-
99
82
  def run():
100
83
  url = f"{self.url}/process/{identifier}/logs/stream"
101
84
  headers = {**settings.headers, **self.sandbox_config.headers}
@@ -133,18 +116,14 @@ class SyncSandboxProcess(SyncSandboxAction):
133
116
  # Ignore on close
134
117
  if not closed.is_set():
135
118
  raise e
136
-
137
119
  thread = threading.Thread(target=run, daemon=True)
138
120
  thread.start()
139
-
140
121
  def close():
141
122
  closed.set()
142
-
143
123
  return {"close": close}
144
124
 
145
125
  def exec(
146
- self,
147
- process: Union[ProcessRequest, ProcessRequestWithLog, Dict[str, Any]],
126
+ self, process: Union[ProcessRequest, ProcessRequestWithLog, Dict[str, Any]]
148
127
  ) -> Union[ProcessResponse, ProcessResponseWithLog]:
149
128
  on_log = None
150
129
  if isinstance(process, ProcessRequestWithLog):
@@ -185,8 +164,7 @@ class SyncSandboxProcess(SyncSandboxAction):
185
164
  if on_log is not None:
186
165
  stream_control = self._stream_logs(result.pid, {"on_log": on_log})
187
166
  return ProcessResponseWithLog(
188
- result,
189
- lambda: stream_control["close"]() if stream_control else None,
167
+ result, lambda: stream_control["close"]() if stream_control else None
190
168
  )
191
169
  return result
192
170
 
@@ -229,11 +207,7 @@ class SyncSandboxProcess(SyncSandboxAction):
229
207
  self.handle_response_error(response)
230
208
  return SuccessResponse.from_dict(response.json())
231
209
 
232
- def logs(
233
- self,
234
- identifier: str,
235
- log_type: Literal["stdout", "stderr", "all"] = "all",
236
- ) -> str:
210
+ def logs(self, identifier: str, log_type: Literal["stdout", "stderr", "all"] = "all") -> str:
237
211
  with self.get_client() as client_instance:
238
212
  response = client_instance.get(f"/process/{identifier}/logs")
239
213
  self.handle_response_error(response)
@@ -245,3 +219,5 @@ class SyncSandboxProcess(SyncSandboxAction):
245
219
  elif log_type == "stderr":
246
220
  return data.get("stderr", "")
247
221
  raise Exception("Unsupported log type")
222
+
223
+
@@ -100,8 +100,7 @@ class SyncSandboxInstance:
100
100
  or "expires" in (sandbox if isinstance(sandbox, dict) else sandbox.__dict__)
101
101
  or "region" in (sandbox if isinstance(sandbox, dict) else sandbox.__dict__)
102
102
  or "lifecycle" in (sandbox if isinstance(sandbox, dict) else sandbox.__dict__)
103
- or "snapshot_enabled"
104
- in (sandbox if isinstance(sandbox, dict) else sandbox.__dict__)
103
+ or "snapshot_enabled" in (sandbox if isinstance(sandbox, dict) else sandbox.__dict__)
105
104
  )
106
105
  )
107
106
  ):
@@ -123,11 +122,7 @@ class SyncSandboxInstance:
123
122
  metadata=Metadata(name=name),
124
123
  spec=SandboxSpec(
125
124
  runtime=Runtime(
126
- image=image,
127
- memory=memory,
128
- ports=ports,
129
- envs=envs,
130
- generation="mk3",
125
+ image=image, memory=memory, ports=ports, envs=envs, generation="mk3"
131
126
  ),
132
127
  volumes=volumes,
133
128
  ),
@@ -188,9 +183,7 @@ class SyncSandboxInstance:
188
183
  return response
189
184
 
190
185
  @classmethod
191
- def update_metadata(
192
- cls, sandbox_name: str, metadata: SandboxUpdateMetadata
193
- ) -> "SyncSandboxInstance":
186
+ def update_metadata(cls, sandbox_name: str, metadata: SandboxUpdateMetadata) -> "SyncSandboxInstance":
194
187
  sandbox_instance = cls.get(sandbox_name)
195
188
  sandbox = sandbox_instance.sandbox
196
189
  updated_sandbox = Sandbox.from_dict(sandbox.to_dict())
@@ -243,9 +236,7 @@ class SyncSandboxInstance:
243
236
  raise e
244
237
 
245
238
  @classmethod
246
- def from_session(
247
- cls, session: Union[SessionWithToken, Dict[str, Any]]
248
- ) -> "SyncSandboxInstance":
239
+ def from_session(cls, session: Union[SessionWithToken, Dict[str, Any]]) -> "SyncSandboxInstance":
249
240
  if isinstance(session, dict):
250
241
  session = SessionWithToken.from_dict(session)
251
242
  sandbox_name = session.name.split("-")[0] if "-" in session.name else session.name
@@ -256,3 +247,5 @@ class SyncSandboxInstance:
256
247
  headers={"X-Blaxel-Preview-Token": session.token},
257
248
  params={"bl_preview_token": session.token},
258
249
  )
250
+
251
+
@@ -22,9 +22,7 @@ class SyncSandboxSessions:
22
22
  def sandbox_name(self) -> str:
23
23
  return self.sandbox_config.metadata.name if self.sandbox_config.metadata else ""
24
24
 
25
- def create(
26
- self, options: Union[SessionCreateOptions, Dict[str, Any]] | None = None
27
- ) -> SessionWithToken:
25
+ def create(self, options: Union[SessionCreateOptions, Dict[str, Any]] | None = None) -> SessionWithToken:
28
26
  if options is None:
29
27
  options = SessionCreateOptions()
30
28
  elif isinstance(options, dict):
@@ -114,9 +112,9 @@ class SyncSandboxSessions:
114
112
  return delete_sandbox_preview.sync(self.sandbox_name, name, client=client)
115
113
 
116
114
  def get_token(self, preview_name: str):
117
- tokens_response = list_sandbox_preview_tokens.sync(
118
- self.sandbox_name, preview_name, client=client
119
- )
115
+ tokens_response = list_sandbox_preview_tokens.sync(self.sandbox_name, preview_name, client=client)
120
116
  if not tokens_response:
121
117
  return None
122
118
  return tokens_response[0]
119
+
120
+
@@ -148,8 +148,7 @@ class SandboxCreateConfiguration:
148
148
  memory: int | None = None,
149
149
  ports: Union[List[Port], List[Dict[str, Any]]] | None = None,
150
150
  envs: List[Dict[str, str]] | None = None,
151
- volumes: Union[List[VolumeBinding], List[VolumeAttachment], List[Dict[str, Any]]]
152
- | None = None,
151
+ volumes: Union[List[VolumeBinding], List[VolumeAttachment], List[Dict[str, Any]]] | None = None,
153
152
  ttl: str | None = None,
154
153
  expires: datetime | None = None,
155
154
  region: str | None = None,