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.
@@ -0,0 +1,9 @@
1
+ .venv/
2
+ __pycache__/
3
+ *.pyc
4
+ .pytest_cache/
5
+ .mypy_cache/
6
+ .ruff_cache/
7
+ dist/
8
+ build/
9
+ *.egg-info/
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
+ ]