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.
Files changed (38) hide show
  1. {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/PKG-INFO +1 -1
  2. {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/opencomputer/__init__.py +1 -1
  3. {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/opencomputer/image.py +35 -20
  4. {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/opencomputer/sandbox.py +4 -0
  5. {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/pyproject.toml +1 -1
  6. {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/.gitignore +0 -0
  7. {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/README.md +0 -0
  8. {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/examples/run_all_tests.py +0 -0
  9. {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/examples/stream_demo.py +0 -0
  10. {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/examples/test_commands.py +0 -0
  11. {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/examples/test_concurrent.py +0 -0
  12. {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/examples/test_declarative_images.py +0 -0
  13. {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/examples/test_default_template.py +0 -0
  14. {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/examples/test_disk_size.py +0 -0
  15. {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/examples/test_domain_tls.py +0 -0
  16. {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/examples/test_environment.py +0 -0
  17. {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/examples/test_exec.py +0 -0
  18. {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/examples/test_file_ops.py +0 -0
  19. {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/examples/test_large_files.py +0 -0
  20. {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/examples/test_multi_template.py +0 -0
  21. {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/examples/test_python_sdk.py +0 -0
  22. {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/examples/test_reconnect.py +0 -0
  23. {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/examples/test_secret_store_fork.py +0 -0
  24. {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/examples/test_secretstore.py +0 -0
  25. {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/examples/test_shell.py +0 -0
  26. {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/examples/test_timeout.py +0 -0
  27. {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/opencomputer/agent.py +0 -0
  28. {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/opencomputer/commands.py +0 -0
  29. {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/opencomputer/exec.py +0 -0
  30. {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/opencomputer/filesystem.py +0 -0
  31. {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/opencomputer/mounts.py +0 -0
  32. {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/opencomputer/project.py +0 -0
  33. {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/opencomputer/pty.py +0 -0
  34. {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/opencomputer/shell.py +0 -0
  35. {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/opencomputer/snapshot.py +0 -0
  36. {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/opencomputer/sse.py +0 -0
  37. {opencomputer_sdk-0.6.2 → opencomputer_sdk-0.6.3}/opencomputer/template.py +0 -0
  38. {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.2
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
@@ -65,4 +65,4 @@ __all__ = [
65
65
  "TagKeyInfo",
66
66
  ]
67
67
 
68
- __version__ = "0.6.0"
68
+ __version__ = "0.6.3"
@@ -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 Image(
64
- _base=self._base,
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 Image(
71
- _base=self._base,
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 Image(
78
- _base=self._base,
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 Image(
85
- _base=self._base,
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 Image(
92
- _base=self._base,
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 Image(
105
- _base=self._base,
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 Image(
125
- _base=self._base,
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 Image(
151
- _base=self._base,
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
- return {
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
- """Compute a deterministic content hash for caching."""
167
- canonical = json.dumps(self.to_dict(), sort_keys=True, separators=(",", ":"))
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,
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "opencomputer-sdk"
7
- version = "0.6.2"
7
+ version = "0.6.3"
8
8
  description = "Python SDK for OpenComputer - cloud sandbox platform"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"