daimon-sdk 0.4.7__tar.gz → 0.4.8__tar.gz
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.
- {daimon_sdk-0.4.7 → daimon_sdk-0.4.8}/PKG-INFO +2 -1
- {daimon_sdk-0.4.7 → daimon_sdk-0.4.8}/README.md +1 -0
- {daimon_sdk-0.4.7 → daimon_sdk-0.4.8}/pyproject.toml +1 -1
- {daimon_sdk-0.4.7 → daimon_sdk-0.4.8}/src/daimon_sdk/manager.py +23 -1
- {daimon_sdk-0.4.7 → daimon_sdk-0.4.8}/tests/test_unit.py +37 -0
- {daimon_sdk-0.4.7 → daimon_sdk-0.4.8}/uv.lock +1 -1
- {daimon_sdk-0.4.7 → daimon_sdk-0.4.8}/.github/workflows/publish.yml +0 -0
- {daimon_sdk-0.4.7 → daimon_sdk-0.4.8}/.gitignore +0 -0
- {daimon_sdk-0.4.7 → daimon_sdk-0.4.8}/examples/auth.py +0 -0
- {daimon_sdk-0.4.7 → daimon_sdk-0.4.8}/examples/exec_session.py +0 -0
- {daimon_sdk-0.4.7 → daimon_sdk-0.4.8}/examples/files.py +0 -0
- {daimon_sdk-0.4.7 → daimon_sdk-0.4.8}/examples/manager.py +0 -0
- {daimon_sdk-0.4.7 → daimon_sdk-0.4.8}/examples/runtime_and_web.py +0 -0
- {daimon_sdk-0.4.7 → daimon_sdk-0.4.8}/src/daimon_sdk/__init__.py +0 -0
- {daimon_sdk-0.4.7 → daimon_sdk-0.4.8}/src/daimon_sdk/_transport.py +0 -0
- {daimon_sdk-0.4.7 → daimon_sdk-0.4.8}/src/daimon_sdk/client.py +0 -0
- {daimon_sdk-0.4.7 → daimon_sdk-0.4.8}/src/daimon_sdk/exceptions.py +0 -0
- {daimon_sdk-0.4.7 → daimon_sdk-0.4.8}/src/daimon_sdk/models.py +0 -0
- {daimon_sdk-0.4.7 → daimon_sdk-0.4.8}/tests/conftest.py +0 -0
- {daimon_sdk-0.4.7 → daimon_sdk-0.4.8}/tests/test_e2e.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: daimon-sdk
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.8
|
|
4
4
|
Summary: Typed async Python SDK for daimon MCP services.
|
|
5
5
|
Author: processd contributors
|
|
6
6
|
License: MIT
|
|
@@ -113,6 +113,7 @@ print(read.file.content)
|
|
|
113
113
|
- `await manager.health()`
|
|
114
114
|
- `await manager.capacity()`
|
|
115
115
|
- `await manager.create_sandbox()`
|
|
116
|
+
- `await manager.list_sandboxes(labels=..., states=...)`
|
|
116
117
|
- `await manager.find_sandbox(labels={"thread_id": thread_id})`
|
|
117
118
|
- `await manager.find_or_create_sandbox(labels={"thread_id": thread_id})`
|
|
118
119
|
- `await manager.get_sandbox(id)`
|
|
@@ -99,6 +99,7 @@ print(read.file.content)
|
|
|
99
99
|
- `await manager.health()`
|
|
100
100
|
- `await manager.capacity()`
|
|
101
101
|
- `await manager.create_sandbox()`
|
|
102
|
+
- `await manager.list_sandboxes(labels=..., states=...)`
|
|
102
103
|
- `await manager.find_sandbox(labels={"thread_id": thread_id})`
|
|
103
104
|
- `await manager.find_or_create_sandbox(labels={"thread_id": thread_id})`
|
|
104
105
|
- `await manager.get_sandbox(id)`
|
|
@@ -63,9 +63,10 @@ class ManagerHTTPTransport:
|
|
|
63
63
|
method: str,
|
|
64
64
|
path: str,
|
|
65
65
|
*,
|
|
66
|
+
params: dict[str, Any] | None = None,
|
|
66
67
|
body: dict[str, Any] | None = None,
|
|
67
68
|
) -> dict[str, Any]:
|
|
68
|
-
response = await self.request(method, path, json=body)
|
|
69
|
+
response = await self.request(method, path, params=params, json=body)
|
|
69
70
|
payload = response.json()
|
|
70
71
|
if not isinstance(payload, dict):
|
|
71
72
|
raise DaimonConnectionError(f"manager response was not a JSON object: {payload!r}")
|
|
@@ -241,6 +242,27 @@ class DaimonManagerClient:
|
|
|
241
242
|
info = self._sandbox_info(await self._transport.json("POST", "/sandboxes"))
|
|
242
243
|
return DaimonSandbox(self, info, timeout_s=self.timeout_s)
|
|
243
244
|
|
|
245
|
+
async def list_sandboxes(
|
|
246
|
+
self,
|
|
247
|
+
*,
|
|
248
|
+
labels: dict[str, str] | None = None,
|
|
249
|
+
states: list[str] | tuple[str, ...] | None = None,
|
|
250
|
+
) -> list[SandboxInfo]:
|
|
251
|
+
params: dict[str, Any] = {}
|
|
252
|
+
if states:
|
|
253
|
+
params["state"] = list(states)
|
|
254
|
+
for key, value in (labels or {}).items():
|
|
255
|
+
params[f"label.{key}"] = value
|
|
256
|
+
payload = await self._transport.json(
|
|
257
|
+
"GET",
|
|
258
|
+
"/sandboxes",
|
|
259
|
+
params=params or None,
|
|
260
|
+
)
|
|
261
|
+
sandboxes = payload.get("sandboxes")
|
|
262
|
+
if not isinstance(sandboxes, list):
|
|
263
|
+
raise DaimonConnectionError("manager response missing sandboxes list")
|
|
264
|
+
return [self._sandbox_info(dict(item)) for item in sandboxes]
|
|
265
|
+
|
|
244
266
|
async def find_or_create_sandbox(
|
|
245
267
|
self,
|
|
246
268
|
*,
|
|
@@ -337,6 +337,43 @@ async def test_daimon_sandbox_lifecycle_updates_info_and_closes_client() -> None
|
|
|
337
337
|
assert sandbox.info.ttl_seconds == 0
|
|
338
338
|
|
|
339
339
|
|
|
340
|
+
@pytest.mark.asyncio
|
|
341
|
+
async def test_manager_list_sandboxes_gets_filtered_sandbox_list(monkeypatch) -> None:
|
|
342
|
+
from daimon_sdk.manager import DaimonManagerClient
|
|
343
|
+
|
|
344
|
+
captured: dict[str, object] = {}
|
|
345
|
+
second = dict(SANDBOX_PAYLOAD)
|
|
346
|
+
second["id"] = "sandbox-2"
|
|
347
|
+
second["state"] = "stopped"
|
|
348
|
+
|
|
349
|
+
async def fake_json(method: str, path: str, *, params=None, body=None):
|
|
350
|
+
captured["method"] = method
|
|
351
|
+
captured["path"] = path
|
|
352
|
+
captured["params"] = params
|
|
353
|
+
captured["body"] = body
|
|
354
|
+
return {"sandboxes": [dict(SANDBOX_PAYLOAD), second]}
|
|
355
|
+
|
|
356
|
+
manager = DaimonManagerClient("http://127.0.0.1:18080")
|
|
357
|
+
monkeypatch.setattr(manager._transport, "json", fake_json)
|
|
358
|
+
|
|
359
|
+
sandboxes = await manager.list_sandboxes(
|
|
360
|
+
labels={"thread_id": "thread-a"},
|
|
361
|
+
states=["running", "stopped"],
|
|
362
|
+
)
|
|
363
|
+
|
|
364
|
+
assert [sandbox.id for sandbox in sandboxes] == ["sandbox-1", "sandbox-2"]
|
|
365
|
+
assert sandboxes[1].state == "stopped"
|
|
366
|
+
assert captured == {
|
|
367
|
+
"method": "GET",
|
|
368
|
+
"path": "/sandboxes",
|
|
369
|
+
"params": {
|
|
370
|
+
"state": ["running", "stopped"],
|
|
371
|
+
"label.thread_id": "thread-a",
|
|
372
|
+
},
|
|
373
|
+
"body": None,
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
|
|
340
377
|
@pytest.mark.asyncio
|
|
341
378
|
async def test_manager_find_sandbox_posts_labels(monkeypatch) -> None:
|
|
342
379
|
from daimon_sdk.manager import DaimonManagerClient, DaimonSandbox
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|