blaxel 0.2.26rc119__py3-none-any.whl → 0.2.28__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.
- blaxel/__init__.py +2 -2
- blaxel/core/__init__.py +9 -1
- blaxel/core/client/api/{privateclusters/create_private_cluster.py → images/cleanup_images.py} +31 -25
- blaxel/core/client/models/__init__.py +2 -4
- blaxel/core/client/models/agent.py +1 -0
- blaxel/core/client/models/agent_spec.py +1 -24
- blaxel/core/client/models/billable_time_metric.py +1 -0
- blaxel/core/{sandbox/client/models/find_match.py → client/models/cleanup_images_response_200.py} +19 -19
- blaxel/core/client/models/configuration.py +1 -0
- blaxel/core/client/models/core_event.py +9 -0
- blaxel/core/client/models/core_spec.py +1 -24
- blaxel/core/client/models/core_spec_configurations.py +1 -0
- blaxel/core/client/models/create_job_execution_request.py +1 -0
- blaxel/core/client/models/create_job_execution_response.py +1 -0
- blaxel/core/client/models/custom_domain.py +1 -0
- blaxel/core/client/models/custom_domain_metadata.py +1 -0
- blaxel/core/client/models/custom_domain_spec.py +1 -0
- blaxel/core/client/models/delete_volume_template_version_response_200.py +1 -0
- blaxel/core/client/models/entrypoint.py +1 -0
- blaxel/core/client/models/form.py +1 -0
- blaxel/core/client/models/function.py +1 -0
- blaxel/core/client/models/function_spec.py +1 -24
- blaxel/core/client/models/image.py +1 -0
- blaxel/core/client/models/image_spec.py +1 -0
- blaxel/core/client/models/integration.py +1 -0
- blaxel/core/client/models/integration_connection.py +1 -0
- blaxel/core/client/models/integration_connection_spec.py +1 -0
- blaxel/core/client/models/integration_endpoint.py +1 -0
- blaxel/core/client/models/integration_endpoints.py +2 -0
- blaxel/core/client/models/job.py +1 -0
- blaxel/core/client/models/job_execution.py +1 -0
- blaxel/core/client/models/job_execution_spec.py +1 -0
- blaxel/core/client/models/job_execution_task.py +1 -0
- blaxel/core/client/models/job_metrics.py +1 -0
- blaxel/core/client/models/job_spec.py +1 -24
- blaxel/core/client/models/jobs_network_chart.py +1 -0
- blaxel/core/client/models/jobs_success_failed_chart.py +1 -0
- blaxel/core/client/models/latency_metric.py +1 -0
- blaxel/core/client/models/location_response.py +1 -0
- blaxel/core/client/models/mcp_definition.py +1 -0
- blaxel/core/client/models/metadata.py +1 -0
- blaxel/core/client/models/metrics.py +34 -0
- blaxel/core/client/models/model.py +1 -0
- blaxel/core/client/models/model_spec.py +1 -24
- blaxel/core/client/models/pending_invitation_accept.py +1 -0
- blaxel/core/client/models/pending_invitation_render.py +1 -0
- blaxel/core/client/models/policy.py +1 -0
- blaxel/core/client/models/policy_spec.py +1 -0
- blaxel/core/client/models/preview.py +1 -0
- blaxel/core/client/models/preview_spec.py +1 -0
- blaxel/core/client/models/preview_token.py +1 -0
- blaxel/core/client/models/public_ips.py +1 -0
- blaxel/core/client/models/request_duration_over_time_metrics.py +1 -0
- blaxel/core/client/models/request_total_by_origin_metric.py +1 -0
- blaxel/core/client/models/request_total_metric.py +1 -0
- blaxel/core/client/models/resource_metrics.py +1 -0
- blaxel/core/client/models/revision_configuration.py +9 -0
- blaxel/core/client/models/runtime.py +1 -0
- blaxel/core/client/models/sandbox.py +1 -0
- blaxel/core/client/models/sandbox_definition.py +1 -0
- blaxel/core/client/models/sandbox_lifecycle.py +1 -0
- blaxel/core/client/models/sandbox_spec.py +1 -24
- blaxel/core/client/models/serverless_config.py +1 -0
- blaxel/core/client/models/start_sandbox.py +1 -0
- blaxel/core/client/models/stop_sandbox.py +1 -0
- blaxel/core/client/models/store_agent.py +1 -0
- blaxel/core/client/models/store_configuration.py +1 -0
- blaxel/core/client/models/template.py +1 -0
- blaxel/core/client/models/time_to_first_token_over_time_metrics.py +1 -0
- blaxel/core/client/models/token_rate_metrics.py +1 -0
- blaxel/core/client/models/trigger.py +10 -0
- blaxel/core/client/models/trigger_configuration.py +28 -0
- blaxel/core/client/models/volume.py +1 -0
- blaxel/core/client/models/volume_template.py +1 -0
- blaxel/core/client/models/websocket_channel.py +9 -0
- blaxel/core/client/models/workspace.py +1 -0
- blaxel/core/client/response_interceptor.py +0 -1
- blaxel/core/common/__init__.py +10 -0
- blaxel/core/common/autoload.py +5 -4
- blaxel/core/common/settings.py +29 -0
- blaxel/core/common/webhook.py +187 -0
- blaxel/core/jobs/__init__.py +355 -8
- blaxel/core/sandbox/client/models/__init__.py +0 -16
- blaxel/core/sandbox/default/action.py +10 -27
- blaxel/core/sandbox/default/filesystem.py +52 -187
- blaxel/core/sandbox/default/interpreter.py +55 -62
- blaxel/core/sandbox/default/process.py +46 -66
- blaxel/core/sandbox/sync/filesystem.py +5 -2
- blaxel/googleadk/model.py +0 -1
- blaxel/livekit/model.py +0 -1
- {blaxel-0.2.26rc119.dist-info → blaxel-0.2.28.dist-info}/METADATA +2 -2
- {blaxel-0.2.26rc119.dist-info → blaxel-0.2.28.dist-info}/RECORD +94 -117
- blaxel/core/client/api/privateclusters/__init__.py +0 -0
- blaxel/core/client/api/privateclusters/delete_private_cluster.py +0 -152
- blaxel/core/client/api/privateclusters/get_private_cluster.py +0 -155
- blaxel/core/client/api/privateclusters/get_private_cluster_health.py +0 -97
- blaxel/core/client/api/privateclusters/list_private_clusters.py +0 -136
- blaxel/core/client/api/privateclusters/update_private_cluster.py +0 -152
- blaxel/core/client/api/privateclusters/update_private_cluster_health.py +0 -97
- blaxel/core/client/models/model_private_cluster.py +0 -79
- blaxel/core/client/models/private_cluster.py +0 -183
- blaxel/core/sandbox/client/api/filesystem/delete_filesystem_tree_path.py +0 -188
- blaxel/core/sandbox/client/api/filesystem/get_filesystem_content_search_path.py +0 -265
- blaxel/core/sandbox/client/api/filesystem/get_filesystem_find_path.py +0 -248
- blaxel/core/sandbox/client/api/filesystem/get_filesystem_search_path.py +0 -237
- blaxel/core/sandbox/client/api/filesystem/get_filesystem_tree_path.py +0 -197
- blaxel/core/sandbox/client/api/filesystem/put_filesystem_tree_path.py +0 -223
- blaxel/core/sandbox/client/api/websocket/__init__.py +0 -0
- blaxel/core/sandbox/client/api/websocket/get_ws.py +0 -81
- blaxel/core/sandbox/client/models/content_search_match.py +0 -98
- blaxel/core/sandbox/client/models/content_search_response.py +0 -97
- blaxel/core/sandbox/client/models/find_response.py +0 -88
- blaxel/core/sandbox/client/models/fuzzy_search_match.py +0 -78
- blaxel/core/sandbox/client/models/fuzzy_search_response.py +0 -88
- blaxel/core/sandbox/client/models/tree_request.py +0 -76
- blaxel/core/sandbox/client/models/tree_request_files.py +0 -49
- {blaxel-0.2.26rc119.dist-info → blaxel-0.2.28.dist-info}/WHEEL +0 -0
- {blaxel-0.2.26rc119.dist-info → blaxel-0.2.28.dist-info}/licenses/LICENSE +0 -0
|
@@ -200,37 +200,40 @@ class SandboxProcess(SandboxAction):
|
|
|
200
200
|
# Always start process without wait_for_completion to avoid server-side blocking
|
|
201
201
|
if should_wait_for_completion and on_log is not None:
|
|
202
202
|
process.wait_for_completion = False
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
203
|
+
async with self.get_client() as client_instance:
|
|
204
|
+
response = await client_instance.post("/process", json=process.to_dict())
|
|
205
|
+
# Parse JSON response only once, with better error handling
|
|
206
|
+
response_data = None
|
|
207
|
+
if response.content:
|
|
208
|
+
try:
|
|
209
|
+
response_data = response.json()
|
|
210
|
+
except Exception:
|
|
211
|
+
# If JSON parsing fails, check the response first
|
|
212
|
+
self.handle_response_error(response)
|
|
213
|
+
raise
|
|
214
|
+
|
|
208
215
|
self.handle_response_error(response)
|
|
209
|
-
import json
|
|
210
|
-
response_data = json.loads(content_bytes) if content_bytes else None
|
|
211
216
|
result = ProcessResponse.from_dict(response_data)
|
|
212
|
-
finally:
|
|
213
|
-
await response.aclose()
|
|
214
217
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
stream_control = self._stream_logs(result.pid, {"on_log": on_log})
|
|
218
|
-
try:
|
|
219
|
-
# Wait for process completion
|
|
220
|
-
result = await self.wait(result.pid, interval=500, max_wait=1000 * 60 * 60)
|
|
221
|
-
finally:
|
|
222
|
-
# Clean up log streaming
|
|
223
|
-
if stream_control:
|
|
224
|
-
stream_control["close"]()
|
|
225
|
-
else:
|
|
226
|
-
# For non-blocking execution, set up log streaming immediately if requested
|
|
227
|
-
if on_log is not None:
|
|
218
|
+
# Handle wait_for_completion with parallel log streaming
|
|
219
|
+
if should_wait_for_completion and on_log is not None:
|
|
228
220
|
stream_control = self._stream_logs(result.pid, {"on_log": on_log})
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
221
|
+
try:
|
|
222
|
+
# Wait for process completion
|
|
223
|
+
result = await self.wait(result.pid, interval=500, max_wait=1000 * 60 * 60)
|
|
224
|
+
finally:
|
|
225
|
+
# Clean up log streaming
|
|
226
|
+
if stream_control:
|
|
227
|
+
stream_control["close"]()
|
|
228
|
+
else:
|
|
229
|
+
# For non-blocking execution, set up log streaming immediately if requested
|
|
230
|
+
if on_log is not None:
|
|
231
|
+
stream_control = self._stream_logs(result.pid, {"on_log": on_log})
|
|
232
|
+
return ProcessResponseWithLog(
|
|
233
|
+
result, lambda: stream_control["close"]() if stream_control else None
|
|
234
|
+
)
|
|
235
|
+
|
|
236
|
+
return result
|
|
234
237
|
|
|
235
238
|
async def wait(
|
|
236
239
|
self, identifier: str, max_wait: int = 60000, interval: int = 1000
|
|
@@ -254,58 +257,37 @@ class SandboxProcess(SandboxAction):
|
|
|
254
257
|
return data
|
|
255
258
|
|
|
256
259
|
async def get(self, identifier: str) -> ProcessResponse:
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
response = await client.get(f"/process/{identifier}")
|
|
260
|
-
try:
|
|
261
|
-
data = json.loads(await response.aread())
|
|
260
|
+
async with self.get_client() as client_instance:
|
|
261
|
+
response = await client_instance.get(f"/process/{identifier}")
|
|
262
262
|
self.handle_response_error(response)
|
|
263
|
-
return ProcessResponse.from_dict(
|
|
264
|
-
finally:
|
|
265
|
-
await response.aclose()
|
|
263
|
+
return ProcessResponse.from_dict(response.json())
|
|
266
264
|
|
|
267
265
|
async def list(self) -> list[ProcessResponse]:
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
response = await client.get("/process")
|
|
271
|
-
try:
|
|
272
|
-
data = json.loads(await response.aread())
|
|
266
|
+
async with self.get_client() as client_instance:
|
|
267
|
+
response = await client_instance.get("/process")
|
|
273
268
|
self.handle_response_error(response)
|
|
274
|
-
return [ProcessResponse.from_dict(item) for item in
|
|
275
|
-
finally:
|
|
276
|
-
await response.aclose()
|
|
269
|
+
return [ProcessResponse.from_dict(item) for item in response.json()]
|
|
277
270
|
|
|
278
271
|
async def stop(self, identifier: str) -> SuccessResponse:
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
response = await client.delete(f"/process/{identifier}")
|
|
282
|
-
try:
|
|
283
|
-
data = json.loads(await response.aread())
|
|
272
|
+
async with self.get_client() as client_instance:
|
|
273
|
+
response = await client_instance.delete(f"/process/{identifier}")
|
|
284
274
|
self.handle_response_error(response)
|
|
285
|
-
return SuccessResponse.from_dict(
|
|
286
|
-
finally:
|
|
287
|
-
await response.aclose()
|
|
275
|
+
return SuccessResponse.from_dict(response.json())
|
|
288
276
|
|
|
289
277
|
async def kill(self, identifier: str) -> SuccessResponse:
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
response = await client.delete(f"/process/{identifier}/kill")
|
|
293
|
-
try:
|
|
294
|
-
data = json.loads(await response.aread())
|
|
278
|
+
async with self.get_client() as client_instance:
|
|
279
|
+
response = await client_instance.delete(f"/process/{identifier}/kill")
|
|
295
280
|
self.handle_response_error(response)
|
|
296
|
-
return SuccessResponse.from_dict(
|
|
297
|
-
finally:
|
|
298
|
-
await response.aclose()
|
|
281
|
+
return SuccessResponse.from_dict(response.json())
|
|
299
282
|
|
|
300
283
|
async def logs(
|
|
301
284
|
self, identifier: str, log_type: Literal["stdout", "stderr", "all"] = "all"
|
|
302
285
|
) -> str:
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
response = await client.get(f"/process/{identifier}/logs")
|
|
306
|
-
try:
|
|
307
|
-
data = json.loads(await response.aread())
|
|
286
|
+
async with self.get_client() as client_instance:
|
|
287
|
+
response = await client_instance.get(f"/process/{identifier}/logs")
|
|
308
288
|
self.handle_response_error(response)
|
|
289
|
+
|
|
290
|
+
data = response.json()
|
|
309
291
|
if log_type == "all":
|
|
310
292
|
return data.get("logs", "")
|
|
311
293
|
elif log_type == "stdout":
|
|
@@ -314,5 +296,3 @@ class SandboxProcess(SandboxAction):
|
|
|
314
296
|
return data.get("stderr", "")
|
|
315
297
|
|
|
316
298
|
raise Exception("Unsupported log type")
|
|
317
|
-
finally:
|
|
318
|
-
await response.aclose()
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import io
|
|
2
2
|
import json
|
|
3
|
+
import logging
|
|
3
4
|
import threading
|
|
4
5
|
from pathlib import Path
|
|
5
6
|
from typing import Any, Callable, Dict, List, Union
|
|
@@ -16,6 +17,8 @@ from ..types import (
|
|
|
16
17
|
)
|
|
17
18
|
from .action import SyncSandboxAction
|
|
18
19
|
|
|
20
|
+
logger = logging.getLogger(__name__)
|
|
21
|
+
|
|
19
22
|
# Multipart upload constants
|
|
20
23
|
MULTIPART_THRESHOLD = 5 * 1024 * 1024 # 5MB
|
|
21
24
|
CHUNK_SIZE = 5 * 1024 * 1024 # 5MB per part
|
|
@@ -256,7 +259,7 @@ class SyncSandboxFileSystem(SyncSandboxAction):
|
|
|
256
259
|
with self.get_client() as client_instance:
|
|
257
260
|
response = client_instance.delete(url, headers=headers)
|
|
258
261
|
if not response.is_success:
|
|
259
|
-
|
|
262
|
+
logger.warning(f"Failed to abort multipart upload: {response.status_code}")
|
|
260
263
|
|
|
261
264
|
def _upload_with_multipart(self, path: str, data: bytes, permissions: str = "0644") -> SuccessResponse:
|
|
262
265
|
init_response = self._initiate_multipart_upload(path, permissions)
|
|
@@ -293,7 +296,7 @@ class SyncSandboxFileSystem(SyncSandboxAction):
|
|
|
293
296
|
try:
|
|
294
297
|
self._abort_multipart_upload(upload_id)
|
|
295
298
|
except Exception as abort_error:
|
|
296
|
-
|
|
299
|
+
logger.warning(f"Failed to abort multipart upload: {abort_error}")
|
|
297
300
|
raise error
|
|
298
301
|
|
|
299
302
|
|
blaxel/googleadk/model.py
CHANGED
blaxel/livekit/model.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: blaxel
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.28
|
|
4
4
|
Summary: Blaxel - AI development platform SDK
|
|
5
5
|
Project-URL: Homepage, https://blaxel.ai
|
|
6
6
|
Project-URL: Documentation, https://docs.blaxel.ai
|
|
@@ -10,7 +10,7 @@ Author-email: cploujoux <cploujoux@blaxel.ai>
|
|
|
10
10
|
License-File: LICENSE
|
|
11
11
|
Requires-Python: >=3.10
|
|
12
12
|
Requires-Dist: attrs>=21.3.0
|
|
13
|
-
Requires-Dist: httpx
|
|
13
|
+
Requires-Dist: httpx>=0.27.0
|
|
14
14
|
Requires-Dist: mcp>=1.9.4
|
|
15
15
|
Requires-Dist: pydantic>=2.0.0
|
|
16
16
|
Requires-Dist: pyjwt>=2.0.0
|