boxxkite-client 0.2.3__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,117 @@
1
+ Metadata-Version: 2.4
2
+ Name: boxxkite-client
3
+ Version: 0.2.3
4
+ Summary: Python client for a hosted boxxkite control-plane (sandbox creation, exec, files, LangChain tools).
5
+ License: Apache-2.0
6
+ Project-URL: Homepage, https://github.com/EvAlssment/boxxkite
7
+ Project-URL: Repository, https://github.com/EvAlssment/boxxkite
8
+ Project-URL: Issues, https://github.com/EvAlssment/boxxkite/issues
9
+ Requires-Python: >=3.10
10
+ Description-Content-Type: text/markdown
11
+ Requires-Dist: httpx>=0.27
12
+ Requires-Dist: websockets>=13
13
+ Provides-Extra: langchain
14
+ Requires-Dist: langchain-core>=0.3; extra == "langchain"
15
+ Provides-Extra: dev
16
+ Requires-Dist: pytest>=8; extra == "dev"
17
+ Requires-Dist: ruff>=0.6; extra == "dev"
18
+
19
+ # boxxkite-client
20
+
21
+ [![PyPI](https://img.shields.io/pypi/v/boxxkite-client?label=PyPI)](https://pypi.org/project/boxxkite-client/)
22
+
23
+ A Python client for a **hosted** boxxkite control-plane — create sandboxes,
24
+ run commands, edit files, over HTTP. Not the boxxkite package itself
25
+ (`boxxkite-sandbox`, which embeds `SandboxManager` against your own
26
+ Kubernetes cluster) — use this to talk to *someone else's* running
27
+ control-plane, hosted or self-hosted, over its API.
28
+
29
+ ## Install
30
+
31
+ ```bash
32
+ pip install boxxkite-client
33
+ pip install boxxkite-client[langchain] # for create_sandbox_tools
34
+ ```
35
+
36
+ ## Quickstart
37
+
38
+ ```python
39
+ from boxxkite_client import BoxxkiteClient
40
+
41
+ client = BoxxkiteClient(base_url="https://your-control-plane.example.com", api_key="bxk_live_...")
42
+
43
+ with client.sandbox(label="demo") as sb:
44
+ result = sb.exec("python3 -c 'print(1 + 1)'")
45
+ print(result["stdout"]) # "2\n"
46
+
47
+ sb.file_create("notes.txt", "hello from boxxkite-client\n")
48
+ print(sb.view("notes.txt")["content"])
49
+ # sandbox is destroyed automatically here, even if an exception was raised above
50
+ ```
51
+
52
+ Also available: `AsyncBoxxkiteClient` (same shapes, `async`/`await`),
53
+ file/directory search (`ls`/`glob`/`grep`), long-running background
54
+ processes (`start_process`/`get_process_output`/`stop_process`), signed
55
+ preview URLs for exposing a port, an audit-log feed (`get_log`/`watch`),
56
+ interactive human takeover over a raw WebSocket, desktop (GUI) takeover
57
+ over the same raw-WebSocket pattern, secret management
58
+ (`create_secret`/`list_secrets`/`delete_secret`, for use via
59
+ `create_sandbox(secret_names=[...])`), and a `create_sandbox_tools()`
60
+ LangChain factory. Full reference with examples
61
+ for all of these: [`docs/API.md`](https://github.com/EvAlssment/boxxkite/blob/main/docs/API.md).
62
+
63
+ ## Error handling
64
+
65
+ Every non-2xx response raises `BoxxkiteApiError` (`.status_code`, `.code`,
66
+ `.message`). A network-level failure raises `BoxxkiteConnectionError`. Both
67
+ subclass `BoxxkiteError`.
68
+
69
+ ```python
70
+ from boxxkite_client import BoxxkiteApiError
71
+
72
+ try:
73
+ client.exec(sandbox["id"], "echo hi")
74
+ except BoxxkiteApiError as exc:
75
+ if exc.code == "concurrent_sandbox_limit_reached":
76
+ ... # back off, destroy an old session, etc.
77
+ ```
78
+
79
+ ## Retries
80
+
81
+ Automatic retry is **off by default**. Pass a `RetryConfig` to enable it;
82
+ `RetryConfig()` carries sensible defaults (2 retries, exponential backoff
83
+ with full jitter, `Retry-After` honored):
84
+
85
+ ```python
86
+ from boxxkite_client import BoxxkiteClient, RetryConfig
87
+
88
+ client = BoxxkiteClient(base_url="...", api_key="...", retry=RetryConfig())
89
+ ```
90
+
91
+ Only idempotent verbs (`GET`/`HEAD`/`PUT`/`DELETE`/`OPTIONS`) are retried,
92
+ and only on a connection failure or a transient status (429, 500, 502, 503,
93
+ 504) — a non-idempotent `POST` (create-sandbox/secret/webhook) is never
94
+ retried, so this can't double-create a resource. `AsyncBoxxkiteClient` takes
95
+ the same `retry=` argument and awaits its backoff. Every field of
96
+ `RetryConfig` is tunable if the defaults don't fit.
97
+
98
+ ## Development
99
+
100
+ ```bash
101
+ pip install -e ".[dev,langchain]"
102
+ pytest tests/
103
+ ```
104
+
105
+ Tests mock the control-plane with `httpx.MockTransport` — no real deployment needed.
106
+
107
+ ## Related tools
108
+
109
+ Moving an in-progress local Claude Code/Codex CLI/opencode session (full
110
+ conversation history, not just a diff) into a fresh boxxkite sandbox is
111
+ handled by the separate `boxxkite-handoff` CLI, built on this SDK — see
112
+ [`../docs/handoff-adapters.md`](../docs/handoff-adapters.md) and
113
+ [`../handoff-cli/README.md`](../handoff-cli/README.md). Not yet published
114
+ to PyPI.
115
+
116
+ See the [root README](https://github.com/EvAlssment/boxxkite#readme) for
117
+ what boxxkite is and the full self-hosting story.
@@ -0,0 +1,99 @@
1
+ # boxxkite-client
2
+
3
+ [![PyPI](https://img.shields.io/pypi/v/boxxkite-client?label=PyPI)](https://pypi.org/project/boxxkite-client/)
4
+
5
+ A Python client for a **hosted** boxxkite control-plane — create sandboxes,
6
+ run commands, edit files, over HTTP. Not the boxxkite package itself
7
+ (`boxxkite-sandbox`, which embeds `SandboxManager` against your own
8
+ Kubernetes cluster) — use this to talk to *someone else's* running
9
+ control-plane, hosted or self-hosted, over its API.
10
+
11
+ ## Install
12
+
13
+ ```bash
14
+ pip install boxxkite-client
15
+ pip install boxxkite-client[langchain] # for create_sandbox_tools
16
+ ```
17
+
18
+ ## Quickstart
19
+
20
+ ```python
21
+ from boxxkite_client import BoxxkiteClient
22
+
23
+ client = BoxxkiteClient(base_url="https://your-control-plane.example.com", api_key="bxk_live_...")
24
+
25
+ with client.sandbox(label="demo") as sb:
26
+ result = sb.exec("python3 -c 'print(1 + 1)'")
27
+ print(result["stdout"]) # "2\n"
28
+
29
+ sb.file_create("notes.txt", "hello from boxxkite-client\n")
30
+ print(sb.view("notes.txt")["content"])
31
+ # sandbox is destroyed automatically here, even if an exception was raised above
32
+ ```
33
+
34
+ Also available: `AsyncBoxxkiteClient` (same shapes, `async`/`await`),
35
+ file/directory search (`ls`/`glob`/`grep`), long-running background
36
+ processes (`start_process`/`get_process_output`/`stop_process`), signed
37
+ preview URLs for exposing a port, an audit-log feed (`get_log`/`watch`),
38
+ interactive human takeover over a raw WebSocket, desktop (GUI) takeover
39
+ over the same raw-WebSocket pattern, secret management
40
+ (`create_secret`/`list_secrets`/`delete_secret`, for use via
41
+ `create_sandbox(secret_names=[...])`), and a `create_sandbox_tools()`
42
+ LangChain factory. Full reference with examples
43
+ for all of these: [`docs/API.md`](https://github.com/EvAlssment/boxxkite/blob/main/docs/API.md).
44
+
45
+ ## Error handling
46
+
47
+ Every non-2xx response raises `BoxxkiteApiError` (`.status_code`, `.code`,
48
+ `.message`). A network-level failure raises `BoxxkiteConnectionError`. Both
49
+ subclass `BoxxkiteError`.
50
+
51
+ ```python
52
+ from boxxkite_client import BoxxkiteApiError
53
+
54
+ try:
55
+ client.exec(sandbox["id"], "echo hi")
56
+ except BoxxkiteApiError as exc:
57
+ if exc.code == "concurrent_sandbox_limit_reached":
58
+ ... # back off, destroy an old session, etc.
59
+ ```
60
+
61
+ ## Retries
62
+
63
+ Automatic retry is **off by default**. Pass a `RetryConfig` to enable it;
64
+ `RetryConfig()` carries sensible defaults (2 retries, exponential backoff
65
+ with full jitter, `Retry-After` honored):
66
+
67
+ ```python
68
+ from boxxkite_client import BoxxkiteClient, RetryConfig
69
+
70
+ client = BoxxkiteClient(base_url="...", api_key="...", retry=RetryConfig())
71
+ ```
72
+
73
+ Only idempotent verbs (`GET`/`HEAD`/`PUT`/`DELETE`/`OPTIONS`) are retried,
74
+ and only on a connection failure or a transient status (429, 500, 502, 503,
75
+ 504) — a non-idempotent `POST` (create-sandbox/secret/webhook) is never
76
+ retried, so this can't double-create a resource. `AsyncBoxxkiteClient` takes
77
+ the same `retry=` argument and awaits its backoff. Every field of
78
+ `RetryConfig` is tunable if the defaults don't fit.
79
+
80
+ ## Development
81
+
82
+ ```bash
83
+ pip install -e ".[dev,langchain]"
84
+ pytest tests/
85
+ ```
86
+
87
+ Tests mock the control-plane with `httpx.MockTransport` — no real deployment needed.
88
+
89
+ ## Related tools
90
+
91
+ Moving an in-progress local Claude Code/Codex CLI/opencode session (full
92
+ conversation history, not just a diff) into a fresh boxxkite sandbox is
93
+ handled by the separate `boxxkite-handoff` CLI, built on this SDK — see
94
+ [`../docs/handoff-adapters.md`](../docs/handoff-adapters.md) and
95
+ [`../handoff-cli/README.md`](../handoff-cli/README.md). Not yet published
96
+ to PyPI.
97
+
98
+ See the [root README](https://github.com/EvAlssment/boxxkite#readme) for
99
+ what boxxkite is and the full self-hosting story.
@@ -0,0 +1,27 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "boxxkite-client"
7
+ version = "0.2.3"
8
+ description = "Python client for a hosted boxxkite control-plane (sandbox creation, exec, files, LangChain tools)."
9
+ readme = "README.md"
10
+ license = { text = "Apache-2.0" }
11
+ requires-python = ">=3.10"
12
+ dependencies = [
13
+ "httpx>=0.27",
14
+ "websockets>=13",
15
+ ]
16
+
17
+ [project.optional-dependencies]
18
+ langchain = ["langchain-core>=0.3"]
19
+ dev = ["pytest>=8", "ruff>=0.6"]
20
+
21
+ [project.urls]
22
+ Homepage = "https://github.com/EvAlssment/boxxkite"
23
+ Repository = "https://github.com/EvAlssment/boxxkite"
24
+ Issues = "https://github.com/EvAlssment/boxxkite/issues"
25
+
26
+ [tool.setuptools.packages.find]
27
+ where = ["src"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,31 @@
1
+ """boxxkite_client — a Python client for a hosted boxxkite control-plane.
2
+
3
+ from boxxkite_client import BoxxkiteClient
4
+
5
+ client = BoxxkiteClient(base_url="https://your-control-plane", api_key="bxk_live_...")
6
+ with client.sandbox(label="demo") as sb:
7
+ result = sb.exec("echo hello")
8
+ print(result["stdout"])
9
+
10
+ See README.md for the async client and LangChain tool factory.
11
+ """
12
+
13
+ from .client import (
14
+ AsyncBoxxkiteClient,
15
+ AsyncSandboxSession,
16
+ BoxxkiteClient,
17
+ RetryConfig,
18
+ SandboxSession,
19
+ )
20
+ from .exceptions import BoxxkiteApiError, BoxxkiteConnectionError, BoxxkiteError
21
+
22
+ __all__ = [
23
+ "AsyncBoxxkiteClient",
24
+ "AsyncSandboxSession",
25
+ "BoxxkiteApiError",
26
+ "BoxxkiteClient",
27
+ "BoxxkiteConnectionError",
28
+ "BoxxkiteError",
29
+ "RetryConfig",
30
+ "SandboxSession",
31
+ ]