zipbox 0.1.0__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.
- zipbox-0.1.0/.gitignore +9 -0
- zipbox-0.1.0/PKG-INFO +88 -0
- zipbox-0.1.0/README.md +69 -0
- zipbox-0.1.0/pyproject.toml +60 -0
- zipbox-0.1.0/src/zipbox/__init__.py +91 -0
- zipbox-0.1.0/src/zipbox/_async_client.py +461 -0
- zipbox-0.1.0/src/zipbox/_backoff.py +36 -0
- zipbox-0.1.0/src/zipbox/_client.py +458 -0
- zipbox-0.1.0/src/zipbox/_core.py +708 -0
- zipbox-0.1.0/src/zipbox/_effects.py +256 -0
- zipbox-0.1.0/src/zipbox/_errors.py +145 -0
- zipbox-0.1.0/src/zipbox/_models.py +197 -0
- zipbox-0.1.0/src/zipbox/_pty.py +640 -0
- zipbox-0.1.0/src/zipbox/_sse.py +62 -0
- zipbox-0.1.0/src/zipbox/_transport.py +133 -0
- zipbox-0.1.0/src/zipbox/py.typed +0 -0
- zipbox-0.1.0/tests/conftest.py +4 -0
- zipbox-0.1.0/tests/mock_server.py +130 -0
- zipbox-0.1.0/tests/test_conformance.py +272 -0
- zipbox-0.1.0/tests/test_pty.py +282 -0
- zipbox-0.1.0/tests/test_streams.py +206 -0
- zipbox-0.1.0/tests/test_units.py +167 -0
- zipbox-0.1.0/uv.lock +876 -0
zipbox-0.1.0/.gitignore
ADDED
zipbox-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: zipbox
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Drive Zipbox boxes from Python: create, exec, files, PTY, previews.
|
|
5
|
+
Project-URL: Homepage, https://zipbox.ai
|
|
6
|
+
Project-URL: Documentation, https://zipbox.ai/docs/sdk-python
|
|
7
|
+
Project-URL: Repository, https://github.com/tribes-protocol/zipbox-sdks
|
|
8
|
+
Author: Tribes Protocol
|
|
9
|
+
License-Expression: Apache-2.0
|
|
10
|
+
Keywords: agents,mcp,sandbox,vm,zipbox
|
|
11
|
+
Classifier: Operating System :: OS Independent
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
14
|
+
Classifier: Typing :: Typed
|
|
15
|
+
Requires-Python: >=3.10
|
|
16
|
+
Requires-Dist: httpx>=0.27
|
|
17
|
+
Requires-Dist: websockets>=13.0
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
|
|
20
|
+
# zipbox
|
|
21
|
+
|
|
22
|
+
Drive [Zipbox](https://zipbox.ai) boxes from Python: create a box, run commands, move
|
|
23
|
+
files, open a terminal, publish a port. Boxes are long-lived machines — nothing on a box
|
|
24
|
+
stops on a clock, and no SDK call has a default timeout.
|
|
25
|
+
|
|
26
|
+
```sh
|
|
27
|
+
pip install zipbox
|
|
28
|
+
export ZIPBOX_API_KEY=zb_… # zipbox.ai → Settings → API keys
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Quickstart
|
|
32
|
+
|
|
33
|
+
```python
|
|
34
|
+
from zipbox import Zipbox
|
|
35
|
+
|
|
36
|
+
zb = Zipbox()
|
|
37
|
+
box = zb.sandboxes.get_or_create("demo")
|
|
38
|
+
result = box.exec("echo hello from $(hostname)")
|
|
39
|
+
print(result.exit_code, result.stdout)
|
|
40
|
+
box.files.write("notes/hello.txt", "hi")
|
|
41
|
+
print(box.preview.create(3000).url)
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Async is the same surface with `await`:
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
from zipbox import AsyncZipbox
|
|
48
|
+
|
|
49
|
+
async with AsyncZipbox() as zb:
|
|
50
|
+
box = await zb.sandboxes.get_or_create("demo")
|
|
51
|
+
print((await box.exec("uname -a")).stdout)
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## What is in it
|
|
55
|
+
|
|
56
|
+
| Area | Calls |
|
|
57
|
+
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
58
|
+
| Lifecycle | `zb.sandboxes.create(name=, tier=)`, `get_or_create`, `list`, `get`, `start`, `stop`, `restart`, `delete`, `set_tier`; `zb.sandbox(id)` |
|
|
59
|
+
| Exec | `box.exec(cmd)` → `ExecResult(id, exit_code, stdout, stderr)`; `exec_stream(cmd)`; `exec_background(cmd)` → `Command`; `run_code("python", code)` |
|
|
60
|
+
| Commands | `Command.get()`, `events(since=)`, `wait()`, `stdin(data)`, `close_stdin()`, `signal("TERM")`; `box.commands.list/get/events/stdin/signal` |
|
|
61
|
+
| Files | `box.files.read`, `read_text`, `write`, `list`, `stat`, `mkdir`, `move`, `delete`, `upload`, `download` |
|
|
62
|
+
| PTY | `box.pty.create(cols=, rows=)` / `attach(session_id)` → `write`, `resize`, `on_data`, iterate, `detach`, `close`, `wait` |
|
|
63
|
+
| Previews | `box.preview.create(port, label=)` → `Preview(url, label)`; `remove(label)` |
|
|
64
|
+
| Other | `box.logs(since=)`, `box.ssh_info()`, `box.screenshot()`, `zb.account.balance()`, `usage()` |
|
|
65
|
+
|
|
66
|
+
A string command runs under `bash -lc` (your PATH, nvm, pyenv); a list is spawned as argv.
|
|
67
|
+
A command that exits non-zero is a result: check `exit_code`. Relative paths resolve
|
|
68
|
+
against `/root/workspace`.
|
|
69
|
+
|
|
70
|
+
`exec` and `exec_stream` kill the command if you disconnect before it exits. A command
|
|
71
|
+
started with `exec_background` keeps running with nobody attached — re-attach any time
|
|
72
|
+
with `box.commands.handle(id).events(since=cursor)`.
|
|
73
|
+
|
|
74
|
+
## Errors
|
|
75
|
+
|
|
76
|
+
Every failure raises `ZipboxError` with `code` (`invalid_request`, `unauthorized`,
|
|
77
|
+
`forbidden`, `not_found`, `insufficient_credits`, `conflict`, `rate_limited`,
|
|
78
|
+
`box_not_running`, `unavailable`), `status`, `message`, `request_id`, `retryable`,
|
|
79
|
+
`retry_after_ms` and `docs_url`. `rate_limited` and `unavailable` are retried
|
|
80
|
+
automatically on reads and on `create` (`max_retries`, default 3).
|
|
81
|
+
|
|
82
|
+
## Configuration
|
|
83
|
+
|
|
84
|
+
`Zipbox(api_key=None, base_url=None, max_retries=3, http_client=None)`. The key and URL
|
|
85
|
+
default to `ZIPBOX_API_KEY` and `ZIPBOX_API_URL` (else `https://api.tribes.xyz`).
|
|
86
|
+
|
|
87
|
+
Docs: [zipbox.ai/docs/sdk-python](https://zipbox.ai/docs/sdk-python) · Agent index:
|
|
88
|
+
[zipbox.ai/llms.txt](https://zipbox.ai/llms.txt) · Apache-2.0.
|
zipbox-0.1.0/README.md
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# zipbox
|
|
2
|
+
|
|
3
|
+
Drive [Zipbox](https://zipbox.ai) boxes from Python: create a box, run commands, move
|
|
4
|
+
files, open a terminal, publish a port. Boxes are long-lived machines — nothing on a box
|
|
5
|
+
stops on a clock, and no SDK call has a default timeout.
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
pip install zipbox
|
|
9
|
+
export ZIPBOX_API_KEY=zb_… # zipbox.ai → Settings → API keys
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Quickstart
|
|
13
|
+
|
|
14
|
+
```python
|
|
15
|
+
from zipbox import Zipbox
|
|
16
|
+
|
|
17
|
+
zb = Zipbox()
|
|
18
|
+
box = zb.sandboxes.get_or_create("demo")
|
|
19
|
+
result = box.exec("echo hello from $(hostname)")
|
|
20
|
+
print(result.exit_code, result.stdout)
|
|
21
|
+
box.files.write("notes/hello.txt", "hi")
|
|
22
|
+
print(box.preview.create(3000).url)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Async is the same surface with `await`:
|
|
26
|
+
|
|
27
|
+
```python
|
|
28
|
+
from zipbox import AsyncZipbox
|
|
29
|
+
|
|
30
|
+
async with AsyncZipbox() as zb:
|
|
31
|
+
box = await zb.sandboxes.get_or_create("demo")
|
|
32
|
+
print((await box.exec("uname -a")).stdout)
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## What is in it
|
|
36
|
+
|
|
37
|
+
| Area | Calls |
|
|
38
|
+
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
39
|
+
| Lifecycle | `zb.sandboxes.create(name=, tier=)`, `get_or_create`, `list`, `get`, `start`, `stop`, `restart`, `delete`, `set_tier`; `zb.sandbox(id)` |
|
|
40
|
+
| Exec | `box.exec(cmd)` → `ExecResult(id, exit_code, stdout, stderr)`; `exec_stream(cmd)`; `exec_background(cmd)` → `Command`; `run_code("python", code)` |
|
|
41
|
+
| Commands | `Command.get()`, `events(since=)`, `wait()`, `stdin(data)`, `close_stdin()`, `signal("TERM")`; `box.commands.list/get/events/stdin/signal` |
|
|
42
|
+
| Files | `box.files.read`, `read_text`, `write`, `list`, `stat`, `mkdir`, `move`, `delete`, `upload`, `download` |
|
|
43
|
+
| PTY | `box.pty.create(cols=, rows=)` / `attach(session_id)` → `write`, `resize`, `on_data`, iterate, `detach`, `close`, `wait` |
|
|
44
|
+
| Previews | `box.preview.create(port, label=)` → `Preview(url, label)`; `remove(label)` |
|
|
45
|
+
| Other | `box.logs(since=)`, `box.ssh_info()`, `box.screenshot()`, `zb.account.balance()`, `usage()` |
|
|
46
|
+
|
|
47
|
+
A string command runs under `bash -lc` (your PATH, nvm, pyenv); a list is spawned as argv.
|
|
48
|
+
A command that exits non-zero is a result: check `exit_code`. Relative paths resolve
|
|
49
|
+
against `/root/workspace`.
|
|
50
|
+
|
|
51
|
+
`exec` and `exec_stream` kill the command if you disconnect before it exits. A command
|
|
52
|
+
started with `exec_background` keeps running with nobody attached — re-attach any time
|
|
53
|
+
with `box.commands.handle(id).events(since=cursor)`.
|
|
54
|
+
|
|
55
|
+
## Errors
|
|
56
|
+
|
|
57
|
+
Every failure raises `ZipboxError` with `code` (`invalid_request`, `unauthorized`,
|
|
58
|
+
`forbidden`, `not_found`, `insufficient_credits`, `conflict`, `rate_limited`,
|
|
59
|
+
`box_not_running`, `unavailable`), `status`, `message`, `request_id`, `retryable`,
|
|
60
|
+
`retry_after_ms` and `docs_url`. `rate_limited` and `unavailable` are retried
|
|
61
|
+
automatically on reads and on `create` (`max_retries`, default 3).
|
|
62
|
+
|
|
63
|
+
## Configuration
|
|
64
|
+
|
|
65
|
+
`Zipbox(api_key=None, base_url=None, max_retries=3, http_client=None)`. The key and URL
|
|
66
|
+
default to `ZIPBOX_API_KEY` and `ZIPBOX_API_URL` (else `https://api.tribes.xyz`).
|
|
67
|
+
|
|
68
|
+
Docs: [zipbox.ai/docs/sdk-python](https://zipbox.ai/docs/sdk-python) · Agent index:
|
|
69
|
+
[zipbox.ai/llms.txt](https://zipbox.ai/llms.txt) · Apache-2.0.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling>=1.25"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "zipbox"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Drive Zipbox boxes from Python: create, exec, files, PTY, previews."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "Apache-2.0"
|
|
11
|
+
requires-python = ">=3.10"
|
|
12
|
+
authors = [{ name = "Tribes Protocol" }]
|
|
13
|
+
keywords = ["zipbox", "sandbox", "vm", "agents", "mcp"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Programming Language :: Python :: 3",
|
|
16
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
17
|
+
"Typing :: Typed",
|
|
18
|
+
"Operating System :: OS Independent",
|
|
19
|
+
]
|
|
20
|
+
dependencies = ["httpx>=0.27", "websockets>=13.0"]
|
|
21
|
+
|
|
22
|
+
[project.urls]
|
|
23
|
+
Homepage = "https://zipbox.ai"
|
|
24
|
+
Documentation = "https://zipbox.ai/docs/sdk-python"
|
|
25
|
+
Repository = "https://github.com/tribes-protocol/zipbox-sdks"
|
|
26
|
+
|
|
27
|
+
[dependency-groups]
|
|
28
|
+
dev = ["pytest>=8", "pytest-asyncio>=0.24", "mypy>=1.11", "ruff>=0.6"]
|
|
29
|
+
|
|
30
|
+
[tool.hatch.build.targets.wheel]
|
|
31
|
+
packages = ["src/zipbox"]
|
|
32
|
+
|
|
33
|
+
[tool.pytest.ini_options]
|
|
34
|
+
testpaths = ["tests"]
|
|
35
|
+
asyncio_mode = "auto"
|
|
36
|
+
asyncio_default_fixture_loop_scope = "function"
|
|
37
|
+
|
|
38
|
+
[tool.mypy]
|
|
39
|
+
strict = true
|
|
40
|
+
python_version = "3.10"
|
|
41
|
+
|
|
42
|
+
[tool.ruff]
|
|
43
|
+
line-length = 100
|
|
44
|
+
target-version = "py310"
|
|
45
|
+
|
|
46
|
+
[tool.ruff.lint]
|
|
47
|
+
select = ["E", "F", "W", "I", "B", "UP", "SIM", "RUF"]
|
|
48
|
+
|
|
49
|
+
[tool.ruff.lint.isort]
|
|
50
|
+
known-first-party = ["zipbox", "mock_server"]
|
|
51
|
+
|
|
52
|
+
[[tool.mypy.overrides]]
|
|
53
|
+
module = ["langchain_core.*", "langchain_openai.*", "langgraph.*"]
|
|
54
|
+
ignore_missing_imports = true
|
|
55
|
+
|
|
56
|
+
[[tool.mypy.overrides]]
|
|
57
|
+
module = ["langchain_tool", "langgraph_agent"]
|
|
58
|
+
disallow_untyped_decorators = false
|
|
59
|
+
disallow_any_unimported = false
|
|
60
|
+
warn_return_any = false
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"""Zipbox SDK: drive Zipbox boxes from Python.
|
|
2
|
+
|
|
3
|
+
>>> from zipbox import Zipbox
|
|
4
|
+
>>> zb = Zipbox() # reads ZIPBOX_API_KEY
|
|
5
|
+
>>> box = zb.sandboxes.get_or_create("demo")
|
|
6
|
+
>>> print(box.exec("echo hello").stdout)
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from zipbox._async_client import (
|
|
10
|
+
AsyncAccount,
|
|
11
|
+
AsyncCommand,
|
|
12
|
+
AsyncCommands,
|
|
13
|
+
AsyncFiles,
|
|
14
|
+
AsyncPreviews,
|
|
15
|
+
AsyncPtyApi,
|
|
16
|
+
AsyncSandbox,
|
|
17
|
+
AsyncSandboxes,
|
|
18
|
+
AsyncZipbox,
|
|
19
|
+
)
|
|
20
|
+
from zipbox._client import (
|
|
21
|
+
Account,
|
|
22
|
+
Command,
|
|
23
|
+
Commands,
|
|
24
|
+
Files,
|
|
25
|
+
Previews,
|
|
26
|
+
PtyApi,
|
|
27
|
+
Sandbox,
|
|
28
|
+
Sandboxes,
|
|
29
|
+
Zipbox,
|
|
30
|
+
)
|
|
31
|
+
from zipbox._core import DEFAULT_API_URL, VERSION, WORKSPACE
|
|
32
|
+
from zipbox._errors import ErrorCode, ZipboxError
|
|
33
|
+
from zipbox._models import (
|
|
34
|
+
CommandInfo,
|
|
35
|
+
CommandState,
|
|
36
|
+
ExecEvent,
|
|
37
|
+
ExecResult,
|
|
38
|
+
FileEntry,
|
|
39
|
+
FileKind,
|
|
40
|
+
Language,
|
|
41
|
+
Preview,
|
|
42
|
+
SandboxDetail,
|
|
43
|
+
SandboxInfo,
|
|
44
|
+
Signal,
|
|
45
|
+
SshInfo,
|
|
46
|
+
Tier,
|
|
47
|
+
)
|
|
48
|
+
from zipbox._pty import AsyncPty, Pty
|
|
49
|
+
|
|
50
|
+
__version__ = VERSION
|
|
51
|
+
|
|
52
|
+
__all__ = [
|
|
53
|
+
"DEFAULT_API_URL",
|
|
54
|
+
"WORKSPACE",
|
|
55
|
+
"Account",
|
|
56
|
+
"AsyncAccount",
|
|
57
|
+
"AsyncCommand",
|
|
58
|
+
"AsyncCommands",
|
|
59
|
+
"AsyncFiles",
|
|
60
|
+
"AsyncPreviews",
|
|
61
|
+
"AsyncPty",
|
|
62
|
+
"AsyncPtyApi",
|
|
63
|
+
"AsyncSandbox",
|
|
64
|
+
"AsyncSandboxes",
|
|
65
|
+
"AsyncZipbox",
|
|
66
|
+
"Command",
|
|
67
|
+
"CommandInfo",
|
|
68
|
+
"CommandState",
|
|
69
|
+
"Commands",
|
|
70
|
+
"ErrorCode",
|
|
71
|
+
"ExecEvent",
|
|
72
|
+
"ExecResult",
|
|
73
|
+
"FileEntry",
|
|
74
|
+
"FileKind",
|
|
75
|
+
"Files",
|
|
76
|
+
"Language",
|
|
77
|
+
"Preview",
|
|
78
|
+
"Previews",
|
|
79
|
+
"Pty",
|
|
80
|
+
"PtyApi",
|
|
81
|
+
"Sandbox",
|
|
82
|
+
"SandboxDetail",
|
|
83
|
+
"SandboxInfo",
|
|
84
|
+
"Sandboxes",
|
|
85
|
+
"Signal",
|
|
86
|
+
"SshInfo",
|
|
87
|
+
"Tier",
|
|
88
|
+
"Zipbox",
|
|
89
|
+
"ZipboxError",
|
|
90
|
+
"__version__",
|
|
91
|
+
]
|