tenki 0.5.1__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.
Files changed (58) hide show
  1. tenki/__init__.py +10 -0
  2. tenki/py.typed +0 -0
  3. tenki-0.5.1.dist-info/METADATA +295 -0
  4. tenki-0.5.1.dist-info/RECORD +58 -0
  5. tenki-0.5.1.dist-info/WHEEL +4 -0
  6. tenki_sandbox/__init__.py +164 -0
  7. tenki_sandbox/_convert.py +555 -0
  8. tenki_sandbox/_internal/proto/__init__.py +0 -0
  9. tenki_sandbox/_internal/proto/buf/__init__.py +0 -0
  10. tenki_sandbox/_internal/proto/buf/validate/__init__.py +0 -0
  11. tenki_sandbox/_internal/proto/buf/validate/validate_pb2.py +450 -0
  12. tenki_sandbox/_internal/proto/tenki/__init__.py +0 -0
  13. tenki_sandbox/_internal/proto/tenki/sandbox/__init__.py +0 -0
  14. tenki_sandbox/_internal/proto/tenki/sandbox/v1/__init__.py +0 -0
  15. tenki_sandbox/_internal/proto/tenki/sandbox/v1/registry_pb2.py +225 -0
  16. tenki_sandbox/_internal/proto/tenki/sandbox/v1/registry_pb2_grpc.py +3 -0
  17. tenki_sandbox/_internal/proto/tenki/sandbox/v1/sandbox_pb2.py +936 -0
  18. tenki_sandbox/_internal/proto/tenki/sandbox/v1/sandbox_pb2_grpc.py +3908 -0
  19. tenki_sandbox/_internal/proto/tenki/sandbox/v1/ssh_gateway_client_pb2.py +58 -0
  20. tenki_sandbox/_internal/proto/tenki/sandbox/v1/ssh_gateway_client_pb2_grpc.py +136 -0
  21. tenki_sandbox/_internal/proto/tenki/sandbox/v1/template_pb2.py +402 -0
  22. tenki_sandbox/_internal/proto/tenki/sandbox/v1/template_pb2_grpc.py +3 -0
  23. tenki_sandbox/_pagination.py +8 -0
  24. tenki_sandbox/_pb.py +6 -0
  25. tenki_sandbox/_resource_validation.py +70 -0
  26. tenki_sandbox/_time.py +52 -0
  27. tenki_sandbox/_transport.py +367 -0
  28. tenki_sandbox/aio/__init__.py +35 -0
  29. tenki_sandbox/aio/_transport.py +125 -0
  30. tenki_sandbox/aio/client.py +241 -0
  31. tenki_sandbox/aio/data_plane.py +269 -0
  32. tenki_sandbox/aio/dial.py +150 -0
  33. tenki_sandbox/aio/fs.py +166 -0
  34. tenki_sandbox/aio/git.py +72 -0
  35. tenki_sandbox/aio/preview_url.py +85 -0
  36. tenki_sandbox/aio/process.py +233 -0
  37. tenki_sandbox/aio/registry.py +193 -0
  38. tenki_sandbox/aio/resources.py +556 -0
  39. tenki_sandbox/aio/sandbox.py +556 -0
  40. tenki_sandbox/aio/ssh.py +172 -0
  41. tenki_sandbox/aio/tunnel.py +444 -0
  42. tenki_sandbox/client.py +373 -0
  43. tenki_sandbox/constants.py +23 -0
  44. tenki_sandbox/data_plane.py +246 -0
  45. tenki_sandbox/dial.py +121 -0
  46. tenki_sandbox/errors.py +406 -0
  47. tenki_sandbox/fs.py +138 -0
  48. tenki_sandbox/git.py +69 -0
  49. tenki_sandbox/models.py +412 -0
  50. tenki_sandbox/preview_url.py +85 -0
  51. tenki_sandbox/process.py +266 -0
  52. tenki_sandbox/py.typed +1 -0
  53. tenki_sandbox/registry.py +212 -0
  54. tenki_sandbox/resources.py +685 -0
  55. tenki_sandbox/sandbox.py +567 -0
  56. tenki_sandbox/ssh.py +214 -0
  57. tenki_sandbox/template_spec.py +1005 -0
  58. tenki_sandbox/tunnel.py +508 -0
tenki/__init__.py ADDED
@@ -0,0 +1,10 @@
1
+ """Tenki Cloud Python SDK.
2
+
3
+ Canonical import namespace for the Tenki sandbox SDK. Everything is
4
+ re-exported from the implementation package :mod:`tenki_sandbox`, so
5
+ ``from tenki import Sandbox`` and ``from tenki_sandbox import Sandbox`` are
6
+ equivalent. New code should import from ``tenki``.
7
+ """
8
+
9
+ from tenki_sandbox import * # noqa: F401,F403
10
+ from tenki_sandbox import __all__ as __all__
tenki/py.typed ADDED
File without changes
@@ -0,0 +1,295 @@
1
+ Metadata-Version: 2.4
2
+ Name: tenki
3
+ Version: 0.5.1
4
+ Summary: Tenki Cloud Python SDK — cloud sandboxes (microVMs) for AI agents and code execution
5
+ Project-URL: Homepage, https://tenki.cloud
6
+ Project-URL: Documentation, https://tenki.cloud/docs/sandbox/sdk
7
+ Project-URL: Repository, https://github.com/LuxorLabs/tenki-sdk-python
8
+ Project-URL: Issues, https://github.com/LuxorLabs/tenki-sdk-python/issues
9
+ Author: Tenki Cloud
10
+ License-Expression: MIT
11
+ Keywords: agents,ai-agents,cloud,code-execution,code-interpreter,microvm,sandbox,tenki
12
+ Requires-Python: >=3.10
13
+ Requires-Dist: grpcio>=1.73
14
+ Requires-Dist: protobuf>=5.29.5
15
+ Requires-Dist: websocket-client>=1.6
16
+ Provides-Extra: async
17
+ Requires-Dist: websockets>=12; extra == 'async'
18
+ Provides-Extra: dev
19
+ Requires-Dist: grpcio-tools>=1.73; extra == 'dev'
20
+ Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
21
+ Requires-Dist: pytest>=8.0; extra == 'dev'
22
+ Requires-Dist: websockets>=12; extra == 'dev'
23
+ Description-Content-Type: text/markdown
24
+
25
+ # Tenki Python SDK
26
+
27
+ Python SDK for Tenki: cloud sandboxes (microVMs) for AI agents and code execution.
28
+
29
+ ```bash
30
+ pip install tenki
31
+ ```
32
+
33
+ > The SDK is published as `tenki`. Existing code that does
34
+ > `import tenki_sandbox` keeps working (that module ships inside `tenki`), but
35
+ > new code should use `import tenki`.
36
+
37
+ ## Protobuf compatibility
38
+
39
+ The SDK supports `protobuf>=5.29.5` with no upper bound. Its Python bindings are
40
+ temporarily generated with protobuf 5.29.5 so applications that require
41
+ `protobuf<6` can install the SDK alongside dependencies such as Memori.
42
+
43
+ Protobuf 6.31.x emits a benign warning when it loads 5.29.5-generated bindings.
44
+ If a test suite pins that runtime and promotes warnings to errors, scope the
45
+ exception narrowly instead of disabling protobuf's runtime checks:
46
+
47
+ ```toml
48
+ [tool.pytest.ini_options]
49
+ filterwarnings = [
50
+ "ignore:Protobuf gencode version 5\\.29\\.5 is exactly one major version older than the runtime version 6\\.31\\..*:UserWarning:google\\.protobuf\\.runtime_version",
51
+ ]
52
+ ```
53
+
54
+ ```python
55
+ from tenki import Sandbox
56
+
57
+ # create() waits by default via a single server-held request and returns an
58
+ # exec-ready sandbox with data-plane access primed (wait=False to skip).
59
+ with Sandbox.create(cpu_cores=2, memory_mb=4096) as sb:
60
+ result = sb.exec("python3", "-c", "print('hello')")
61
+ result.check()
62
+ print(result.stdout_text)
63
+
64
+ # fs paths are relative to the sandbox workdir (absolute paths must stay inside it)
65
+ sb.fs.write_text("input.txt", "data")
66
+ print(sb.fs.read_text("input.txt"))
67
+
68
+ preview = sb.expose_port(3000, ttl=3600)
69
+ print(preview.url)
70
+ ```
71
+
72
+ The API key determines the Workspace automatically; ordinary Sandbox calls do not require a Workspace ID.
73
+
74
+ ## Async (asyncio)
75
+
76
+ `AsyncClient` / `AsyncSandbox` expose the same surface with native `async`/`await`,
77
+ built on `grpc.aio` — no `asyncio.to_thread` wrapping required. Use it inside any
78
+ asyncio server (FastAPI, aiohttp, etc.).
79
+
80
+ ```python
81
+ import asyncio
82
+ from tenki import AsyncSandbox
83
+
84
+
85
+ async def main():
86
+ async with await AsyncSandbox.create(cpu_cores=2) as sb:
87
+ result = await sb.exec("python3", "-c", "print('hello')")
88
+ result.check()
89
+ print(result.stdout_text)
90
+
91
+ await sb.fs.write_text("input.txt", "data")
92
+ print(await sb.fs.read_text("input.txt"))
93
+
94
+ proc = await sb.start("bash", "-lc", "read name; echo hi $name")
95
+ await proc.write_stdin("tenki\n")
96
+ await proc.close_stdin()
97
+ async for chunk in proc.stdout:
98
+ print(chunk.decode(), end="")
99
+ (await proc.wait()).check()
100
+
101
+
102
+ asyncio.run(main())
103
+ ```
104
+
105
+ The sync `Client` / `Sandbox` remain available for non-async consumers. SSH,
106
+ `dial`, and host-port tunnels are also async: `AsyncSandbox.ssh()` returns an
107
+ `AsyncSSHConn` (raw async `read`/`write`/`close`, matching the TS/Go SDKs; needs
108
+ the `tenki[async]` extra for `websockets`), `dial()` returns an
109
+ `AsyncDialConn`, and `expose_host_port()` / `expose_host_port_resilient()` return
110
+ async tunnels with `await tunnel.terminated.wait()` and `on_terminated` callbacks.
111
+
112
+ ## Auth
113
+
114
+ Auth resolution:
115
+
116
+ 1. `auth_token=` passed to `Client` or `Sandbox.create`
117
+ 2. `TENKI_AUTH_TOKEN`
118
+ 3. `TENKI_API_KEY`
119
+
120
+ `TENKI_API_ENDPOINT` overrides the API URL; legacy `TENKI_API_URL` is also accepted.
121
+
122
+ ## Process API
123
+
124
+ `exec` collects stdout/stderr and returns a result:
125
+
126
+ ```python
127
+ result = sb.exec("npm", "test", cwd="project", timeout=60, env={"CI": "1"})
128
+ print(result.stdout_text)
129
+ result.check()
130
+ ```
131
+
132
+ `start` returns a live process:
133
+
134
+ ```python
135
+ proc = sb.start("bash", "-lc", "read name; echo hello $name")
136
+ proc.write_stdin("tenki\n")
137
+ proc.close_stdin()
138
+ for chunk in proc.stdout:
139
+ print(chunk.decode(), end="")
140
+ proc.wait().check()
141
+ ```
142
+
143
+ Use `shell()` when you want shell parsing:
144
+
145
+ ```python
146
+ sb.shell("python3 -m http.server 3000 >/tmp/server.log 2>&1 &")
147
+ ```
148
+
149
+ Process `cwd` values follow the guest contract: relative paths are normalized
150
+ under the sandbox guest workdir (`/home/tenki` by default), absolute paths are
151
+ used unchanged, and missing or non-directory targets fail before the process
152
+ starts.
153
+
154
+ ## Sandbox lifetime
155
+
156
+ Long-lived sandboxes are a parameter choice at `create()`, not a separate API:
157
+
158
+ ```python
159
+ sb = client.create(
160
+ sticky=True, # long-lived session: not reaped on idle
161
+ idle_timeout_minutes=120, # or: generous idle window before auto-pause
162
+ max_duration=8 * 3600, # total lifetime cap (seconds)
163
+ pause_retention=24 * 3600,# how long a paused session is kept resumable
164
+ )
165
+ ```
166
+
167
+ - `max_duration` caps total lifetime; `sb.extend(seconds)` pushes the deadline
168
+ (`sb.info.timeout_at`) while running.
169
+ - `idle_timeout_minutes` auto-pauses an idle sandbox; `sb.resume()` brings it
170
+ back with the filesystem intact.
171
+ - `sticky=True` opts the session out of idle reaping for keep-warm use cases
172
+ (workspaces cap concurrent sticky sessions).
173
+ - `client.list(sticky=True)` filters for long-lived sessions in the API key's Workspace.
174
+
175
+ ## SSH
176
+
177
+ For tools that speak SSH (paramiko, scp, IDE remote dev), the SDK can mint a
178
+ short-lived OpenSSH user certificate for your session and open a transport to
179
+ the sandbox SSH gateway. No keys are provisioned into the guest; the engine
180
+ signs your local public key and the gateway verifies the certificate.
181
+
182
+ Requires `pip install websocket-client paramiko` (websocket-client for the
183
+ transport, paramiko if you want a client in-process).
184
+
185
+ ```python
186
+ import subprocess
187
+ import paramiko
188
+
189
+ # 1. local keypair (any OpenSSH key works; ed25519 shown)
190
+ subprocess.run(["ssh-keygen", "-t", "ed25519", "-N", "", "-q", "-f", "id_tenki"], check=True)
191
+
192
+ # 2. engine signs a short-lived user cert for this sandbox
193
+ cert = sb.issue_ssh_cert(open("id_tenki.pub").read(), ttl=600)
194
+ open("id_tenki-cert.pub", "w").write(cert.ssh_cert)
195
+
196
+ # 3. open the gateway transport and run a paramiko session over it
197
+ pkey = paramiko.Ed25519Key.from_private_key_file("id_tenki")
198
+ pkey.load_certificate("id_tenki-cert.pub")
199
+
200
+ transport = paramiko.Transport(sb.ssh()) # WebSocket-backed socket
201
+ transport.connect(username="tenki", pkey=pkey)
202
+ session = transport.open_session()
203
+ session.exec_command("echo hello-over-ssh")
204
+ print(session.makefile().read().decode())
205
+ transport.close()
206
+ ```
207
+
208
+ Notes:
209
+
210
+ - `sb.ssh()` / `client.ssh(session_id)` discover an active gateway and return
211
+ `SSHConn`, an `io.RawIOBase` socket usable anywhere paramiko accepts one.
212
+ - The SSH username is `tenki`.
213
+ - `TENKI_SANDBOX_GATEWAY_URL` overrides the gateway WebSocket URL (it is
214
+ otherwise derived from the API endpoint).
215
+ - Certificate RPCs use the Connect protocol over HTTPS (same as the Go SDK and
216
+ the `tenki` CLI), so they work through standard HTTP load balancers.
217
+ - `sb.update_ssh_authorized_keys([...])` additionally plants long-lived public
218
+ keys in the guest's `authorized_keys` if you prefer key-based auth for the
219
+ in-guest sshd.
220
+
221
+ ## Resource APIs
222
+
223
+ ```python
224
+ from tenki import Client, GiB
225
+
226
+ client = Client()
227
+
228
+ volume = client.volumes.create(
229
+ name="cache",
230
+ size_bytes=10 * GiB,
231
+ )
232
+
233
+ preview = client.preview_urls.create(
234
+ slug="demo",
235
+ session_id=sb.id,
236
+ port=3000,
237
+ )
238
+ ```
239
+
240
+ ## Registry
241
+
242
+ Delete an untagged, non-latest, unshared registry version by image and snapshot
243
+ ID:
244
+
245
+ ```python
246
+ result = client.registry.delete_version(
247
+ "11111111-1111-1111-1111-111111111111",
248
+ "55555555-5555-5555-5555-555555555555",
249
+ )
250
+ ```
251
+
252
+ ## Templates (typed builder)
253
+
254
+ `TemplateSpec` is an immutable typed recipe (every builder call returns a new
255
+ value). Builds freeze the normalized spec + `spec_hash` server-side and return
256
+ a private digest-addressed `Image`, the normal sandbox launch source.
257
+
258
+ ```python
259
+ from tenki import Client, TemplateSpec
260
+
261
+ client = Client()
262
+
263
+ spec = (
264
+ TemplateSpec() # defaults to base image "sandbox"
265
+ .from_image("sandbox-v2") # or .from_template(...) / .from_snapshot(...)
266
+ .with_git_context("https://github.com/acme/node-api", "main")
267
+ .run("npm ci", name="Install dependencies")
268
+ .runtime_env({"NODE_ENV": "production"})
269
+ .start(["npm", "start"], ready_when=[{"http": "http://localhost:3000/health"}])
270
+ )
271
+ spec.validate() # aggregate local validation; server stays authoritative
272
+
273
+ template = client.templates.create(name="node-api", spec=spec)
274
+
275
+ build = client.templates.build(
276
+ template, # resource objects in, IDs as fallback
277
+ build_secrets={"GITHUB_TOKEN": token}, # explicit request-time values
278
+ wait_for_completion=True,
279
+ on_event=lambda e: print(e), # one ordered log/progress handler
280
+ )
281
+
282
+ sb = client.create(image=build.image, wait_for_runtime=True)
283
+ ```
284
+
285
+ `wait_build(build_id)` reconnects to an existing build (ordered, deduplicated
286
+ events). Local interruption (Ctrl-C or `cancel_event`) stops observation only;
287
+ `client.templates.cancel_build(build)` cancels remotely. Waited failures raise
288
+ `TemplateBuildFailedError` carrying the final redacted build; runtime waits
289
+ raise `TemplateRuntimeFailedError` without terminating the running sandbox.
290
+ Strict authored JSON import/export: `spec.to_json()` / `TemplateSpec.from_json(text)`.
291
+ Checkout `mode` uses `"contents"` or `"directory"`; runtime `runAt`,
292
+ `restartPolicy`, and `snapshotMode` use short values such as `"build"`,
293
+ `"on-failure"`, and `"memory"`. Full protobuf enum names remain accepted;
294
+ unknown fields and enum values are rejected.
295
+ See `examples/template_builder.py` for the full filesystem/memory workflow.
@@ -0,0 +1,58 @@
1
+ tenki/__init__.py,sha256=Ehndqrw3KWVhieB7e_YJB3zuA03wHhzW7JO9OcPjUwI,389
2
+ tenki/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
3
+ tenki_sandbox/__init__.py,sha256=BYcOwyYmS2Y_PxQrLMChKsXw28PHmP1hEJM0v_USzIU,3974
4
+ tenki_sandbox/_convert.py,sha256=3Fw7njSx5jX0cKoqTHtjXJymD9GA3PgWZOf37I5jc1Y,18279
5
+ tenki_sandbox/_pagination.py,sha256=COO_5BUQXiooFK3Ulb8_FGtPJlaN2uoDu1a_kYcP4Yw,292
6
+ tenki_sandbox/_pb.py,sha256=_s4GkzR1F8gZAZisHcKLC3geoK_lTio4J1lTcHYTugg,401
7
+ tenki_sandbox/_resource_validation.py,sha256=hIY3aKIcI68kY7bZNRK7xhyR2PA81FKpA1w_pzzQQ0o,2231
8
+ tenki_sandbox/_time.py,sha256=4C7X5dwrolIwuj0PrTpY-HI3fiotgPAyBLcvTec826U,1347
9
+ tenki_sandbox/_transport.py,sha256=bpvRQorrjhrMWt2W5y4Tc473Mb6HVj9XV1MEzK1k-1k,13034
10
+ tenki_sandbox/client.py,sha256=6BCm4ipCxaRCE4ri0fE6qkq396_EkPuFhCqMhLvEumQ,13365
11
+ tenki_sandbox/constants.py,sha256=bn7kyHjDMvjZ2Ww2ML7Q8LkjWmk3TlMBvdRccOPUIs0,521
12
+ tenki_sandbox/data_plane.py,sha256=nwzWqUgkI8mWFnbEuPRevg9kNyPnXnJlkYXck4MD2h0,8679
13
+ tenki_sandbox/dial.py,sha256=UYQkmzn_FOHyzFSJTO5pyNIWcxepu4AWo7G_elQw2To,4051
14
+ tenki_sandbox/errors.py,sha256=RUBrYLIboiVSEUORcso6adat_gyEBu9eUQtWYuHFFcA,12001
15
+ tenki_sandbox/fs.py,sha256=yzbZxpht_5ApmJlnYblt7pgH-WDQk8-k-j4EdLloWcQ,4908
16
+ tenki_sandbox/git.py,sha256=e6AT5Qsi1-hGk8x5-L4I7CIHfU8xaTEhDAgen7NyQBY,2194
17
+ tenki_sandbox/models.py,sha256=1f5qudKefUNtDnvvwEaPwEV2jGcJTwXCz3PxciZixKc,9893
18
+ tenki_sandbox/preview_url.py,sha256=brhZwWRhl34l0lsOF2yD9K1JS838HvYVV0QsMF3ycOo,3032
19
+ tenki_sandbox/process.py,sha256=SL8lbpohD_BnLWjeITIGbZzjueo5unU0Cbrt7qnUQwY,9448
20
+ tenki_sandbox/py.typed,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
21
+ tenki_sandbox/registry.py,sha256=TjBhmXAH8Y5yB9jzNdSt9PI9jj5l_6VRaV0aIdA8WjM,7385
22
+ tenki_sandbox/resources.py,sha256=pwJB9r0N-L2uwHb65EJ1AlXEL2nSBTF3zFuA06GYG4A,25105
23
+ tenki_sandbox/sandbox.py,sha256=5vBvkvNNMMA_5v_6XI6OQETTOyS32jeyHLf69wf2mwM,19754
24
+ tenki_sandbox/ssh.py,sha256=gqQEcgQfI1cqOkQdR5_gNRxCdirqyVFlou_DQj8nouI,6548
25
+ tenki_sandbox/template_spec.py,sha256=uPgzoR-BugdYr8tOBDOjLt0zD5t4xw7bF-GGRregyXE,37739
26
+ tenki_sandbox/tunnel.py,sha256=uHTQJZM6ypOfL0WeuPy3BOWhxtXZmyAEtLbTz17HHOc,17473
27
+ tenki_sandbox/_internal/proto/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
+ tenki_sandbox/_internal/proto/buf/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
29
+ tenki_sandbox/_internal/proto/buf/validate/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
30
+ tenki_sandbox/_internal/proto/buf/validate/validate_pb2.py,sha256=HXD5LsgU-4CAvpGLIRfazoXCXRG-b-QlRv3lY1-cUlk,154194
31
+ tenki_sandbox/_internal/proto/tenki/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
32
+ tenki_sandbox/_internal/proto/tenki/sandbox/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
+ tenki_sandbox/_internal/proto/tenki/sandbox/v1/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
+ tenki_sandbox/_internal/proto/tenki/sandbox/v1/registry_pb2.py,sha256=MvuaKGHb3v5VO6DuLeXM3qSX1a1RjI5y7ZZaYsp3ZTk,34209
35
+ tenki_sandbox/_internal/proto/tenki/sandbox/v1/registry_pb2_grpc.py,sha256=xYOs94SXiNYAlFodACnsXW5QovLsHY5tCk3p76RH5Zc,158
36
+ tenki_sandbox/_internal/proto/tenki/sandbox/v1/sandbox_pb2.py,sha256=aE-HHd3omM48qIdXWUm1-Y42JqTZHfqU94UZNzguwzs,151069
37
+ tenki_sandbox/_internal/proto/tenki/sandbox/v1/sandbox_pb2_grpc.py,sha256=bmWRJdmgaAES81iFPugNQRfu0oyRFpn2o3g0WZxZUcc,180052
38
+ tenki_sandbox/_internal/proto/tenki/sandbox/v1/ssh_gateway_client_pb2.py,sha256=nQ8COQfqMYLPpGq5d-21WHpVpEZYFEMjDAUMc0E5log,6099
39
+ tenki_sandbox/_internal/proto/tenki/sandbox/v1/ssh_gateway_client_pb2_grpc.py,sha256=TrC_NiW3IwKblAP05p_-bNrn6uHciT9YHPHBXn1fg8Y,6057
40
+ tenki_sandbox/_internal/proto/tenki/sandbox/v1/template_pb2.py,sha256=mBAXWMMPIrwQKhcMUsVATdT_ijkYsgqgaD8awP2ks_c,63118
41
+ tenki_sandbox/_internal/proto/tenki/sandbox/v1/template_pb2_grpc.py,sha256=xYOs94SXiNYAlFodACnsXW5QovLsHY5tCk3p76RH5Zc,158
42
+ tenki_sandbox/aio/__init__.py,sha256=2jfWY6NjNws1VWylUP783J5yHrEN7bSh4u4CS9P5iY0,1037
43
+ tenki_sandbox/aio/_transport.py,sha256=NgIFSkT6or-6SdYheO7Us7nlr3vKktbc-J2CBCSjyEA,4920
44
+ tenki_sandbox/aio/client.py,sha256=e-YAkYp5MsvwvZUjx94QFhOpZkBiSkQm_jiLDfkoL0g,8895
45
+ tenki_sandbox/aio/data_plane.py,sha256=iZ7cQ9iHSa3D4KW6fgvK6Dbu1KnAW0wdRFU4rQqG1Z4,9777
46
+ tenki_sandbox/aio/dial.py,sha256=cp68SeyawvBfQU3Zt2tBS6k0Llto__OARBkIOfaMMyw,5263
47
+ tenki_sandbox/aio/fs.py,sha256=4XX8yMfmIJfWlwPWBGScHAxU8wVDjs70Yk-WbJNEmLU,6243
48
+ tenki_sandbox/aio/git.py,sha256=e2KttYMjNTkhT3NwTGdKiwXOeSU1P6Qlpj3fDMvE7OQ,2294
49
+ tenki_sandbox/aio/preview_url.py,sha256=3uUblNF3S5A-2TgyFWDqQfqeIVSNx8nGBBzRYtC6EEo,3114
50
+ tenki_sandbox/aio/process.py,sha256=ZQQkU1Sl8AATItIorua7NyGKkhpyEmeTPYtwnQ-unoQ,8745
51
+ tenki_sandbox/aio/registry.py,sha256=bphAiKZT2QV62OptwWcuptMFcvO6qYskJjU_RvHwj3I,7135
52
+ tenki_sandbox/aio/resources.py,sha256=V6H7g4YSNCVMqgnHrOnCoNDSA3S31lTqYSPCoZsfCs8,21187
53
+ tenki_sandbox/aio/sandbox.py,sha256=HmNLVqCOQ1nkm0j3tmFQkybo-KjdU5xh8wX2VG8Hgto,20556
54
+ tenki_sandbox/aio/ssh.py,sha256=O-ONv_QoKzp7dlNRSYYer_M0pREpgjD9Xa51s-fo4Cs,5699
55
+ tenki_sandbox/aio/tunnel.py,sha256=hBFnCFoy6MR7ZB9cKySOwsTRcw6kSRIzEXYrrwcltT0,16831
56
+ tenki-0.5.1.dist-info/METADATA,sha256=kJ5UtxKdgrltvwkj8dyi57OGbhsegeYtwu6RRbOxe04,10350
57
+ tenki-0.5.1.dist-info/WHEEL,sha256=lCkmxWfQsSc9CfIClYeavTdQeEX2toPqufh9gI35EQA,87
58
+ tenki-0.5.1.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.31.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,164 @@
1
+ from .aio import AsyncClient, AsyncSandbox
2
+ from .client import Client
3
+ from .constants import GB, GiB, KB, KiB, MB, MiB, TB, TiB
4
+ from .dial import DialConn
5
+ from .tunnel import HostPortTunnel, ResilientHostPortTunnel
6
+ from .errors import (
7
+ CapabilityUnavailableError,
8
+ CommandFailedError,
9
+ CommandTimeoutError,
10
+ FileNotFoundError,
11
+ GitOperationFailedError,
12
+ InboundDisabledError,
13
+ InvalidResourceConfigError,
14
+ InvalidStateError,
15
+ MissingAuthTokenError,
16
+ PaginationStalledError,
17
+ PermissionDeniedError,
18
+ PortLimitExceededError,
19
+ PrimitiveTimeoutError,
20
+ QuotaExceededError,
21
+ RateLimitedError,
22
+ RegistryImageNotFoundError,
23
+ SSHUnavailableError,
24
+ SandboxError,
25
+ SessionNotFoundError,
26
+ SessionTerminatedError,
27
+ SnapshotNotDurableError,
28
+ SnapshotNotFoundError,
29
+ StreamClosedError,
30
+ TemplateBuildFailedError,
31
+ TemplateBuildInProgressError,
32
+ TemplateBuildWaitCancelledError,
33
+ TemplateRuntimeFailedError,
34
+ TemplateExistsError,
35
+ TemplateNotFoundError,
36
+ TemplateSpecValidationError,
37
+ UnauthorizedError,
38
+ VolumeInUseError,
39
+ VolumeNotFoundError,
40
+ VolumeSyncPendingError,
41
+ )
42
+ from .models import (
43
+ CommandResult,
44
+ ExposedPort,
45
+ FileInfo,
46
+ Identity,
47
+ IdentityWorkspace,
48
+ Image,
49
+ PreviewUrl,
50
+ RegistryImage,
51
+ RegistryImageDetail,
52
+ RegistryImageSummary,
53
+ RegistryListResult,
54
+ RegistryShareGrant,
55
+ RegistryShareResult,
56
+ RegistryTag,
57
+ RegistryVersionDeleteResult,
58
+ ResolvedRegistryRef,
59
+ SSHCert,
60
+ SandboxInfo,
61
+ Snapshot,
62
+ SnapshotDownloadURL,
63
+ Template,
64
+ TemplateBuild,
65
+ TemplateBuildEvent,
66
+ TemplateBuildFailure,
67
+ TemplateBuildLogEvent,
68
+ TemplateBuildProgressEvent,
69
+ TemplateBuildProvenance,
70
+ TemplateBuildStepReference,
71
+ TunnelTermination,
72
+ Volume,
73
+ VolumeAttachment,
74
+ WorkspaceUsageLimit,
75
+ )
76
+ from .sandbox import Sandbox
77
+ from .ssh import SSHConn
78
+ from .template_spec import TemplateSpec
79
+
80
+ __all__ = [
81
+ "Client",
82
+ "Sandbox",
83
+ "AsyncClient",
84
+ "AsyncSandbox",
85
+ "SSHConn",
86
+ "DialConn",
87
+ "HostPortTunnel",
88
+ "ResilientHostPortTunnel",
89
+ "TunnelTermination",
90
+ "WorkspaceUsageLimit",
91
+ "SandboxError",
92
+ "MissingAuthTokenError",
93
+ "PaginationStalledError",
94
+ "UnauthorizedError",
95
+ "PermissionDeniedError",
96
+ "SessionNotFoundError",
97
+ "SessionTerminatedError",
98
+ "InvalidStateError",
99
+ "InvalidResourceConfigError",
100
+ "CommandTimeoutError",
101
+ "FileNotFoundError",
102
+ "GitOperationFailedError",
103
+ "CommandFailedError",
104
+ "CapabilityUnavailableError",
105
+ "PrimitiveTimeoutError",
106
+ "QuotaExceededError",
107
+ "PortLimitExceededError",
108
+ "InboundDisabledError",
109
+ "RateLimitedError",
110
+ "SSHUnavailableError",
111
+ "VolumeNotFoundError",
112
+ "VolumeInUseError",
113
+ "VolumeSyncPendingError",
114
+ "SnapshotNotDurableError",
115
+ "SnapshotNotFoundError",
116
+ "TemplateNotFoundError",
117
+ "TemplateExistsError",
118
+ "TemplateBuildFailedError",
119
+ "TemplateBuildInProgressError",
120
+ "TemplateBuildWaitCancelledError",
121
+ "TemplateRuntimeFailedError",
122
+ "TemplateSpecValidationError",
123
+ "StreamClosedError",
124
+ "RegistryImageNotFoundError",
125
+ "RegistryImage",
126
+ "RegistryImageDetail",
127
+ "RegistryImageSummary",
128
+ "RegistryListResult",
129
+ "RegistryShareGrant",
130
+ "RegistryShareResult",
131
+ "RegistryTag",
132
+ "RegistryVersionDeleteResult",
133
+ "ResolvedRegistryRef",
134
+ "SSHCert",
135
+ "CommandResult",
136
+ "ExposedPort",
137
+ "FileInfo",
138
+ "Identity",
139
+ "IdentityWorkspace",
140
+ "Image",
141
+ "PreviewUrl",
142
+ "SandboxInfo",
143
+ "Snapshot",
144
+ "SnapshotDownloadURL",
145
+ "Template",
146
+ "TemplateBuild",
147
+ "TemplateSpec",
148
+ "TemplateBuildEvent",
149
+ "TemplateBuildFailure",
150
+ "TemplateBuildLogEvent",
151
+ "TemplateBuildProgressEvent",
152
+ "TemplateBuildProvenance",
153
+ "TemplateBuildStepReference",
154
+ "Volume",
155
+ "VolumeAttachment",
156
+ "KB",
157
+ "MB",
158
+ "GB",
159
+ "TB",
160
+ "KiB",
161
+ "MiB",
162
+ "GiB",
163
+ "TiB",
164
+ ]