opencomputer-sdk 0.6.2__tar.gz → 0.6.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.
- {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/PKG-INFO +1 -1
- {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/opencomputer/__init__.py +1 -1
- {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/opencomputer/image.py +35 -20
- {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/opencomputer/sandbox.py +4 -0
- {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/pyproject.toml +1 -1
- {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/.gitignore +0 -0
- {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/README.md +0 -0
- {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/examples/run_all_tests.py +0 -0
- {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/examples/stream_demo.py +0 -0
- {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/examples/test_commands.py +0 -0
- {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/examples/test_concurrent.py +0 -0
- {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/examples/test_declarative_images.py +0 -0
- {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/examples/test_default_template.py +0 -0
- {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/examples/test_disk_size.py +0 -0
- {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/examples/test_domain_tls.py +0 -0
- {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/examples/test_environment.py +0 -0
- {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/examples/test_exec.py +0 -0
- {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/examples/test_file_ops.py +0 -0
- {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/examples/test_large_files.py +0 -0
- {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/examples/test_multi_template.py +0 -0
- {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/examples/test_python_sdk.py +0 -0
- {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/examples/test_reconnect.py +0 -0
- {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/examples/test_secret_store_fork.py +0 -0
- {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/examples/test_secretstore.py +0 -0
- {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/examples/test_shell.py +0 -0
- {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/examples/test_timeout.py +0 -0
- {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/opencomputer/agent.py +0 -0
- {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/opencomputer/commands.py +0 -0
- {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/opencomputer/exec.py +0 -0
- {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/opencomputer/filesystem.py +0 -0
- {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/opencomputer/mounts.py +0 -0
- {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/opencomputer/project.py +0 -0
- {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/opencomputer/pty.py +0 -0
- {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/opencomputer/shell.py +0 -0
- {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/opencomputer/snapshot.py +0 -0
- {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/opencomputer/sse.py +0 -0
- {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/opencomputer/template.py +0 -0
- {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/opencomputer/usage.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: opencomputer-sdk
|
|
3
|
-
Version: 0.6.
|
|
3
|
+
Version: 0.6.3
|
|
4
4
|
Summary: Python SDK for OpenComputer - cloud sandbox platform
|
|
5
5
|
Project-URL: Homepage, https://github.com/diggerhq/opensandbox
|
|
6
6
|
Project-URL: Repository, https://github.com/diggerhq/opensandbox
|
|
@@ -6,7 +6,7 @@ import base64
|
|
|
6
6
|
import hashlib
|
|
7
7
|
import json
|
|
8
8
|
import os
|
|
9
|
-
from dataclasses import dataclass, field
|
|
9
|
+
from dataclasses import dataclass, field, replace
|
|
10
10
|
from typing import Any
|
|
11
11
|
|
|
12
12
|
|
|
@@ -47,6 +47,10 @@ class Image:
|
|
|
47
47
|
|
|
48
48
|
_base: str = "base"
|
|
49
49
|
_steps: tuple[ImageStep, ...] = field(default_factory=tuple)
|
|
50
|
+
# RAM for the build phase (apt/pip). 0 = server default. Does not pin the
|
|
51
|
+
# output image — the server re-snapshots at the default 1 GB floor, and you
|
|
52
|
+
# size the actual sandbox at create time via memory_mb.
|
|
53
|
+
_builder_memory_mb: int = 0
|
|
50
54
|
|
|
51
55
|
@classmethod
|
|
52
56
|
def base(cls) -> Image:
|
|
@@ -60,36 +64,36 @@ class Image:
|
|
|
60
64
|
|
|
61
65
|
def apt_install(self, packages: list[str]) -> Image:
|
|
62
66
|
"""Install system packages via apt-get."""
|
|
63
|
-
return
|
|
64
|
-
|
|
67
|
+
return replace(
|
|
68
|
+
self,
|
|
65
69
|
_steps=(*self._steps, ImageStep("apt_install", {"packages": packages})),
|
|
66
70
|
)
|
|
67
71
|
|
|
68
72
|
def pip_install(self, packages: list[str]) -> Image:
|
|
69
73
|
"""Install Python packages via pip."""
|
|
70
|
-
return
|
|
71
|
-
|
|
74
|
+
return replace(
|
|
75
|
+
self,
|
|
72
76
|
_steps=(*self._steps, ImageStep("pip_install", {"packages": packages})),
|
|
73
77
|
)
|
|
74
78
|
|
|
75
79
|
def run_commands(self, *commands: str) -> Image:
|
|
76
80
|
"""Run one or more shell commands."""
|
|
77
|
-
return
|
|
78
|
-
|
|
81
|
+
return replace(
|
|
82
|
+
self,
|
|
79
83
|
_steps=(*self._steps, ImageStep("run", {"commands": list(commands)})),
|
|
80
84
|
)
|
|
81
85
|
|
|
82
86
|
def env(self, vars: dict[str, str]) -> Image:
|
|
83
87
|
"""Set environment variables (written to /etc/environment)."""
|
|
84
|
-
return
|
|
85
|
-
|
|
88
|
+
return replace(
|
|
89
|
+
self,
|
|
86
90
|
_steps=(*self._steps, ImageStep("env", {"vars": vars})),
|
|
87
91
|
)
|
|
88
92
|
|
|
89
93
|
def workdir(self, path: str) -> Image:
|
|
90
94
|
"""Set the default working directory."""
|
|
91
|
-
return
|
|
92
|
-
|
|
95
|
+
return replace(
|
|
96
|
+
self,
|
|
93
97
|
_steps=(*self._steps, ImageStep("workdir", {"path": path})),
|
|
94
98
|
)
|
|
95
99
|
|
|
@@ -101,8 +105,8 @@ class Image:
|
|
|
101
105
|
content: String content of the file.
|
|
102
106
|
"""
|
|
103
107
|
encoded = base64.b64encode(content.encode()).decode()
|
|
104
|
-
return
|
|
105
|
-
|
|
108
|
+
return replace(
|
|
109
|
+
self,
|
|
106
110
|
_steps=(*self._steps, ImageStep("add_file", {
|
|
107
111
|
"path": remote_path,
|
|
108
112
|
"content": encoded,
|
|
@@ -121,8 +125,8 @@ class Image:
|
|
|
121
125
|
"""
|
|
122
126
|
with open(local_path, "rb") as f:
|
|
123
127
|
encoded = base64.b64encode(f.read()).decode()
|
|
124
|
-
return
|
|
125
|
-
|
|
128
|
+
return replace(
|
|
129
|
+
self,
|
|
126
130
|
_steps=(*self._steps, ImageStep("add_file", {
|
|
127
131
|
"path": remote_path,
|
|
128
132
|
"content": encoded,
|
|
@@ -147,22 +151,33 @@ class Image:
|
|
|
147
151
|
with open(full, "rb") as f:
|
|
148
152
|
encoded = base64.b64encode(f.read()).decode()
|
|
149
153
|
files.append({"relativePath": rel, "content": encoded})
|
|
150
|
-
return
|
|
151
|
-
|
|
154
|
+
return replace(
|
|
155
|
+
self,
|
|
152
156
|
_steps=(*self._steps, ImageStep("add_dir", {
|
|
153
157
|
"path": remote_path,
|
|
154
158
|
"files": files,
|
|
155
159
|
})),
|
|
156
160
|
)
|
|
157
161
|
|
|
162
|
+
def builder_memory(self, mb: int) -> Image:
|
|
163
|
+
"""Set the RAM (MB) for the build phase. Use this when a build OOMs at the
|
|
164
|
+
default 4 GB (e.g. heavy ``apt``/``pip``/``npm``). Does not affect the
|
|
165
|
+
resulting image's memory — size the sandbox at create time via ``memory_mb``."""
|
|
166
|
+
return replace(self, _builder_memory_mb=mb)
|
|
167
|
+
|
|
158
168
|
def to_dict(self) -> dict[str, Any]:
|
|
159
169
|
"""Returns the manifest as a plain dict (for JSON serialization)."""
|
|
160
|
-
|
|
170
|
+
d: dict[str, Any] = {
|
|
161
171
|
"base": self._base,
|
|
162
172
|
"steps": [s.to_dict() for s in self._steps],
|
|
163
173
|
}
|
|
174
|
+
if self._builder_memory_mb > 0:
|
|
175
|
+
d["builderMemoryMB"] = self._builder_memory_mb
|
|
176
|
+
return d
|
|
164
177
|
|
|
165
178
|
def cache_key(self) -> str:
|
|
166
|
-
"""
|
|
167
|
-
|
|
179
|
+
"""Deterministic content hash for caching. Memory knobs are resource
|
|
180
|
+
params, not image content, so they're excluded (matches the server)."""
|
|
181
|
+
content = {"base": self._base, "steps": [s.to_dict() for s in self._steps]}
|
|
182
|
+
canonical = json.dumps(content, sort_keys=True, separators=(",", ":"))
|
|
168
183
|
return hashlib.sha256(canonical.encode()).hexdigest()
|
|
@@ -83,6 +83,10 @@ class Sandbox:
|
|
|
83
83
|
_client: httpx.AsyncClient = field(default=None, repr=False)
|
|
84
84
|
_data_client: httpx.AsyncClient = field(default=None, repr=False)
|
|
85
85
|
|
|
86
|
+
@property
|
|
87
|
+
def id(self) -> str:
|
|
88
|
+
return self.sandbox_id
|
|
89
|
+
|
|
86
90
|
@classmethod
|
|
87
91
|
async def create(
|
|
88
92
|
cls,
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|