createos-sandbox 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.
Files changed (41) hide show
  1. createos_sandbox-0.1.0/.github/workflows/ci.yml +82 -0
  2. createos_sandbox-0.1.0/.gitignore +12 -0
  3. createos_sandbox-0.1.0/CHANGELOG.md +29 -0
  4. createos_sandbox-0.1.0/CONTRIBUTING.md +69 -0
  5. createos_sandbox-0.1.0/LICENSE +21 -0
  6. createos_sandbox-0.1.0/PKG-INFO +384 -0
  7. createos_sandbox-0.1.0/README.md +350 -0
  8. createos_sandbox-0.1.0/SECURITY.md +31 -0
  9. createos_sandbox-0.1.0/examples/command_streaming/README.md +12 -0
  10. createos_sandbox-0.1.0/examples/command_streaming/main.py +58 -0
  11. createos_sandbox-0.1.0/examples/custom_template/README.md +13 -0
  12. createos_sandbox-0.1.0/examples/custom_template/main.py +159 -0
  13. createos_sandbox-0.1.0/examples/desktop/README.md +13 -0
  14. createos_sandbox-0.1.0/examples/desktop/main.py +138 -0
  15. createos_sandbox-0.1.0/examples/execution_server/README.md +43 -0
  16. createos_sandbox-0.1.0/examples/execution_server/main.py +268 -0
  17. createos_sandbox-0.1.0/examples/files_and_snapshots/README.md +12 -0
  18. createos_sandbox-0.1.0/examples/files_and_snapshots/main.py +102 -0
  19. createos_sandbox-0.1.0/examples/hello_world/README.md +11 -0
  20. createos_sandbox-0.1.0/examples/hello_world/main.py +28 -0
  21. createos_sandbox-0.1.0/examples/ingress_preview/README.md +13 -0
  22. createos_sandbox-0.1.0/examples/ingress_preview/main.py +66 -0
  23. createos_sandbox-0.1.0/examples/managed_process/README.md +12 -0
  24. createos_sandbox-0.1.0/examples/managed_process/main.py +196 -0
  25. createos_sandbox-0.1.0/examples/network/README.md +11 -0
  26. createos_sandbox-0.1.0/examples/network/main.py +59 -0
  27. createos_sandbox-0.1.0/pyproject.toml +80 -0
  28. createos_sandbox-0.1.0/scripts/publish.sh +29 -0
  29. createos_sandbox-0.1.0/src/createos/__init__.py +106 -0
  30. createos_sandbox-0.1.0/src/createos/_streams.py +177 -0
  31. createos_sandbox-0.1.0/src/createos/_transport.py +297 -0
  32. createos_sandbox-0.1.0/src/createos/_version.py +1 -0
  33. createos_sandbox-0.1.0/src/createos/client.py +224 -0
  34. createos_sandbox-0.1.0/src/createos/errors.py +76 -0
  35. createos_sandbox-0.1.0/src/createos/instance.py +415 -0
  36. createos_sandbox-0.1.0/src/createos/models.py +833 -0
  37. createos_sandbox-0.1.0/src/createos/py.typed +1 -0
  38. createos_sandbox-0.1.0/src/createos/self.py +27 -0
  39. createos_sandbox-0.1.0/src/createos/services.py +836 -0
  40. createos_sandbox-0.1.0/tests/test_execution_server.py +72 -0
  41. createos_sandbox-0.1.0/tests/test_sdk.py +235 -0
@@ -0,0 +1,82 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ workflow_dispatch:
8
+
9
+ permissions:
10
+ contents: read
11
+
12
+ concurrency:
13
+ group: ci-${{ github.workflow }}-${{ github.ref }}
14
+ cancel-in-progress: true
15
+
16
+ env:
17
+ PIP_DISABLE_PIP_VERSION_CHECK: "1"
18
+ PYTHONUNBUFFERED: "1"
19
+
20
+ jobs:
21
+ test:
22
+ name: Test Python ${{ matrix.python-version }}
23
+ runs-on: ubuntu-latest
24
+ strategy:
25
+ fail-fast: false
26
+ matrix:
27
+ python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
28
+ steps:
29
+ - uses: actions/checkout@v7
30
+ - uses: actions/setup-python@v7
31
+ with:
32
+ python-version: ${{ matrix.python-version }}
33
+ cache: pip
34
+ cache-dependency-path: pyproject.toml
35
+ - name: Install package and development tools
36
+ run: python -m pip install -e '.[dev]'
37
+ - name: Run tests
38
+ run: python -m pytest -q
39
+
40
+ quality:
41
+ name: Quality
42
+ runs-on: ubuntu-latest
43
+ steps:
44
+ - uses: actions/checkout@v7
45
+ - uses: actions/setup-python@v7
46
+ with:
47
+ python-version: "3.14"
48
+ cache: pip
49
+ cache-dependency-path: pyproject.toml
50
+ - name: Install package and development tools
51
+ run: python -m pip install -e '.[dev]'
52
+ - name: Check formatting
53
+ run: python -m ruff format --check src tests examples
54
+ - name: Lint
55
+ run: python -m ruff check src tests examples
56
+ - name: Type check
57
+ run: python -m mypy src/createos --ignore-missing-imports
58
+ - name: Check test coverage
59
+ run: >-
60
+ python -m pytest
61
+ --cov=createos
62
+ --cov-report=term-missing
63
+ --cov-fail-under=70
64
+
65
+ package:
66
+ name: Package
67
+ runs-on: ubuntu-latest
68
+ steps:
69
+ - uses: actions/checkout@v7
70
+ - uses: actions/setup-python@v7
71
+ with:
72
+ python-version: "3.14"
73
+ cache: pip
74
+ cache-dependency-path: pyproject.toml
75
+ - name: Install build frontend
76
+ run: python -m pip install build
77
+ - name: Build source and wheel distributions
78
+ run: python -m build
79
+ - name: Install and import the built wheel
80
+ run: |
81
+ python -m pip install --force-reinstall dist/*.whl
82
+ python -c "import createos; print(createos.__version__)"
@@ -0,0 +1,12 @@
1
+ .venv/
2
+ __pycache__/
3
+ *.py[cod]
4
+ .pytest_cache/
5
+ .mypy_cache/
6
+ .ruff_cache/
7
+ .coverage
8
+ coverage.xml
9
+ htmlcov/
10
+ build/
11
+ dist/
12
+ *.egg-info/
@@ -0,0 +1,29 @@
1
+ # Changelog
2
+
3
+ All notable changes to `createos-sandbox` are documented here.
4
+ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
5
+ Versions follow [Semantic Versioning](https://semver.org/).
6
+
7
+ ## Deprecation policy
8
+
9
+ - Anything re-exported from `src/createos/__init__.py` is part of the public
10
+ API.
11
+ - We are pre-1.0, so the API is allowed to break in MINOR bumps — breaking
12
+ changes ship as MINOR, and PATCH releases are bug-fix only.
13
+ - Where possible, breaking changes are announced one minor before removal: the
14
+ old surface keeps working, gains a `DeprecationWarning`, and this file points
15
+ at the replacement.
16
+
17
+ ## [Unreleased]
18
+
19
+ ## [0.1.0] — 2026-09-11
20
+
21
+ Initial release.
22
+
23
+ - `Client` with sandbox lifecycle (create, pause, resume, fork, destroy),
24
+ command execution and NDJSON streaming, file transfer and snapshots,
25
+ managed processes, networks, ingress previews, and custom templates.
26
+ - Typed wire-contract models, typed errors, and `py.typed`.
27
+
28
+ [Unreleased]: https://github.com/NodeOps-app/createos-python-sdk/compare/v0.1.0...HEAD
29
+ [0.1.0]: https://github.com/NodeOps-app/createos-python-sdk/releases/tag/v0.1.0
@@ -0,0 +1,69 @@
1
+ # Contributing
2
+
3
+ Thank you for contributing to the CreateOS Python SDK.
4
+
5
+ ## Setup
6
+
7
+ Create a virtual environment and install the SDK with its development tools:
8
+
9
+ ```sh
10
+ python -m venv .venv
11
+ .venv/bin/pip install -e '.[dev]'
12
+ ```
13
+
14
+ Run the complete local check suite:
15
+
16
+ ```sh
17
+ .venv/bin/ruff format --check src tests examples
18
+ .venv/bin/ruff check src tests examples
19
+ .venv/bin/mypy src/createos --ignore-missing-imports
20
+ .venv/bin/pytest --cov=createos --cov-fail-under=70
21
+ ```
22
+
23
+ ## Commit convention
24
+
25
+ Use [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/):
26
+
27
+ ```text
28
+ <type>(<optional-scope>): <subject>
29
+ ```
30
+
31
+ Accepted types are `feat`, `fix`, `docs`, `style`, `refactor`, `test`, `chore`,
32
+ and `perf`. Write the subject in imperative mood, keep it at 50 characters or
33
+ fewer, start it with a lowercase letter, and do not end it with a period.
34
+
35
+ Examples:
36
+
37
+ ```text
38
+ feat(sandbox): add disk attachment
39
+ fix(transport): honor retry-after header
40
+ docs(readme): add network example
41
+ test(processes): cover output replay
42
+ chore: prepare v0.1.0 release
43
+ ```
44
+
45
+ For an incompatible public API change, add `!` before the colon and explain the
46
+ change in a `BREAKING CHANGE:` commit footer:
47
+
48
+ ```text
49
+ feat(sandbox)!: change create response
50
+ ```
51
+
52
+ ## Before opening a pull request
53
+
54
+ Run the complete local check suite. Add or update tests for behavior changes,
55
+ and update public docstrings and README examples when the public API changes.
56
+
57
+ ## Releasing
58
+
59
+ The package is published manually to PyPI as `createos-sandbox`.
60
+
61
+ 1. Bump `__version__` in `src/createos/_version.py` (the single source of
62
+ truth — `pyproject.toml` reads it) and move the `CHANGELOG.md`
63
+ `[Unreleased]` entries under the new version.
64
+ 2. Dry run the release gate: `./scripts/publish.sh --dry`.
65
+ 3. Publish: `./scripts/publish.sh`. It reruns tests, lint, types, builds the
66
+ sdist and wheel, uploads with `twine`, then tags and pushes `v<version>`.
67
+
68
+ Uploading needs a PyPI API token, e.g. in `~/.pypirc` or as
69
+ `TWINE_USERNAME=__token__ TWINE_PASSWORD=pypi-...`.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 NodeOps Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,384 @@
1
+ Metadata-Version: 2.5
2
+ Name: createos-sandbox
3
+ Version: 0.1.0
4
+ Summary: Isolated sandboxes for AI agents and untrusted code: create, run commands, egress allowlist, pause/resume/fork, destroy. Python SDK for CreateOS Sandbox.
5
+ Project-URL: Homepage, https://createos.sh
6
+ Project-URL: Repository, https://github.com/NodeOps-app/createos-python-sdk
7
+ Project-URL: Issues, https://github.com/NodeOps-app/createos-python-sdk/issues
8
+ Project-URL: Changelog, https://github.com/NodeOps-app/createos-python-sdk/blob/main/CHANGELOG.md
9
+ Author: NodeOps Inc.
10
+ License: MIT
11
+ License-File: LICENSE
12
+ Keywords: agent,agents,ai,ai-agents,code-execution,compute,createos,createos-sandbox,e2b-alternative,egress,isolated-sandbox,isolation,runtime,sandbox,sdk,untrusted-code
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Programming Language :: Python :: 3 :: Only
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Programming Language :: Python :: 3.14
22
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
23
+ Classifier: Typing :: Typed
24
+ Requires-Python: >=3.10
25
+ Requires-Dist: httpx<1,>=0.27
26
+ Provides-Extra: dev
27
+ Requires-Dist: build>=1.2; extra == 'dev'
28
+ Requires-Dist: mypy>=1.11; extra == 'dev'
29
+ Requires-Dist: pytest-cov>=5; extra == 'dev'
30
+ Requires-Dist: pytest>=8; extra == 'dev'
31
+ Requires-Dist: ruff>=0.6; extra == 'dev'
32
+ Requires-Dist: twine>=5; extra == 'dev'
33
+ Description-Content-Type: text/markdown
34
+
35
+ # CreateOS Python SDK
36
+
37
+ Launch an isolated cloud sandbox, run real commands, stream output, move files,
38
+ open a preview URL, and tear everything down from Python.
39
+
40
+ ## Your first sandbox
41
+
42
+ ```sh
43
+ pip install createos-sandbox
44
+ ```
45
+
46
+ Python 3.10 or newer is required.
47
+
48
+ ```python
49
+ from createos import Client, CreateSandboxRequest, RunCommandRequest
50
+
51
+
52
+ with Client(api_key="your-api-key") as client:
53
+ sandbox = client.create_sandbox(
54
+ CreateSandboxRequest(
55
+ name="hello-python",
56
+ shape="s-4vcpu-4gb",
57
+ rootfs="devbox:1",
58
+ )
59
+ )
60
+ try:
61
+ response = sandbox.run_command(
62
+ RunCommandRequest(
63
+ command="sh",
64
+ arguments=[
65
+ "-c",
66
+ 'printf "Python says hello from $(uname -m)\\n"',
67
+ ],
68
+ )
69
+ )
70
+ print(response.result.standard_output, end="")
71
+ finally:
72
+ sandbox.destroy()
73
+ ```
74
+
75
+ ```text
76
+ Python says hello from x86_64
77
+ ```
78
+
79
+ Do not commit a real API key to source control; inject it through your
80
+ application's secret manager. You can configure the endpoint and default
81
+ request timeout when constructing the client:
82
+
83
+ ```python
84
+ client = Client(
85
+ api_key=api_key,
86
+ base_url="http://localhost:8080",
87
+ timeout=30,
88
+ )
89
+ ```
90
+
91
+ As an alternative, `Client()` reads `CREATEOS_SANDBOX_API_KEY` and
92
+ `CREATEOS_SANDBOX_BASE_URL`. Explicit constructor arguments take precedence.
93
+
94
+ ## Documentation
95
+
96
+ - [CreateOS Sandbox overview](https://nodeops.network/createos/docs/Sandbox/Overview)
97
+ explains the sandbox model, lifecycle, networking, storage, and isolation.
98
+ - [CreateOS Sandbox documentation](https://nodeops.network/createos/docs)
99
+ contains the REST API reference and product guides.
100
+ - [CreateOS Go SDK](https://github.com/NodeOps-app/createos-go-sdk) provides the
101
+ same sandbox capabilities for Go applications.
102
+ - [CreateOS TypeScript SDK](https://github.com/NodeOps-app/createos-sandbox-sdk)
103
+ provides the same sandbox capabilities for JavaScript and TypeScript
104
+ applications.
105
+ - [Runnable examples](#examples) demonstrate complete SDK workflows.
106
+ - The public Python API is typed and documented with Python docstrings.
107
+ - [Contributing guide](CONTRIBUTING.md) documents development checks and commit
108
+ conventions.
109
+
110
+ ## Stream output as it happens
111
+
112
+ Long-running commands do not need to disappear behind a buffered HTTP call:
113
+
114
+ ```python
115
+ import sys
116
+
117
+ from createos import ExecStreamEventType, RunCommandRequest
118
+
119
+
120
+ request = RunCommandRequest(
121
+ command="sh",
122
+ arguments=[
123
+ "-c",
124
+ 'for n in 1 2 3; do echo "step $n"; sleep 1; done',
125
+ ],
126
+ )
127
+
128
+ with sandbox.stream_command(request) as stream:
129
+ for event in stream:
130
+ if event.type is ExecStreamEventType.STDOUT:
131
+ print(event.data, end="")
132
+ elif event.type is ExecStreamEventType.STDERR:
133
+ print(event.data, end="", file=sys.stderr)
134
+ elif event.type is ExecStreamEventType.EXIT:
135
+ print(f"exit code: {event.exit_code}")
136
+ ```
137
+
138
+ Stopping early is safe: leaving the `with` block closes the response body and
139
+ releases the underlying HTTP connection.
140
+
141
+ ## Move files without shell escaping
142
+
143
+ ```python
144
+ sandbox.files.upload(
145
+ "/workspace/config.json",
146
+ b'{"mode":"production"}',
147
+ )
148
+
149
+ with sandbox.files.download("/workspace/config.json") as download:
150
+ contents = download.read()
151
+ ```
152
+
153
+ `upload()` also accepts a binary file-like object, allowing large files to be
154
+ transferred without reading them all into memory first.
155
+
156
+ ## Keep a process alive after disconnecting
157
+
158
+ Managed processes are resources rather than fragile terminal sessions. Start
159
+ one, reconnect from its output sequence, send input or signals, and wait for
160
+ either the leader or its complete process tree:
161
+
162
+ ```python
163
+ from createos import (
164
+ ManagedProcessCreateRequest,
165
+ ManagedProcessWaitOptions,
166
+ ManagedProcessWaitScope,
167
+ )
168
+
169
+
170
+ process = sandbox.processes.create(
171
+ ManagedProcessCreateRequest(
172
+ command="sh",
173
+ arguments=["-c", "sleep 1; echo managed process finished"],
174
+ )
175
+ )
176
+
177
+ finished = sandbox.processes.wait(
178
+ process.process_id,
179
+ ManagedProcessWaitOptions(
180
+ scope=ManagedProcessWaitScope.TREE,
181
+ wait_timeout=30,
182
+ ),
183
+ )
184
+ ```
185
+
186
+ ## Turn a service into a URL
187
+
188
+ Create a sandbox with ingress enabled, wait for the server to listen, then ask
189
+ the instance for its public URL:
190
+
191
+ ```python
192
+ from createos import CreateSandboxRequest, ManagedProcessCreateRequest
193
+
194
+
195
+ sandbox = client.create_sandbox(
196
+ CreateSandboxRequest(
197
+ shape="s-4vcpu-4gb",
198
+ rootfs="devbox:1",
199
+ ingress_enabled=True,
200
+ )
201
+ )
202
+
203
+ sandbox.processes.create(
204
+ ManagedProcessCreateRequest(
205
+ command="python3",
206
+ arguments=[
207
+ "-m",
208
+ "http.server",
209
+ "8080",
210
+ "--bind",
211
+ "0.0.0.0",
212
+ ],
213
+ )
214
+ )
215
+
216
+ sandbox.wait_for_port(8080, host="127.0.0.1", timeout=15)
217
+ print(sandbox.preview_url(8080))
218
+ ```
219
+
220
+ ## Everything is already connected
221
+
222
+ Account-level services are initialized by `Client`:
223
+
224
+ ```python
225
+ templates = client.templates
226
+ networks = client.networks
227
+ disks = client.disks
228
+
229
+ custom_templates = templates.list()
230
+ print(
231
+ f"{len(custom_templates)} templates ready; "
232
+ f"networks={type(networks).__name__} disks={type(disks).__name__}"
233
+ )
234
+ ```
235
+
236
+ Instance-level services are initialized when a sandbox handle is created or
237
+ retrieved:
238
+
239
+ ```python
240
+ sandbox.files
241
+ sandbox.processes
242
+ sandbox.computer.mouse
243
+ sandbox.computer.keyboard
244
+ sandbox.computer.windows
245
+ sandbox.computer.screens
246
+ ```
247
+
248
+ ## Connect sandboxes on a private network
249
+
250
+ Create an overlay network, attach a running sandbox, and inspect the resulting
251
+ membership. Cleanup runs in reverse order, so the sandbox detaches before the
252
+ network is deleted:
253
+
254
+ ```python
255
+ from createos import NetworkCreateRequest
256
+
257
+
258
+ network = client.networks.create(NetworkCreateRequest(name="agent-mesh"))
259
+ try:
260
+ sandbox.attach_network(network.id)
261
+ try:
262
+ connected = client.networks.get(network.id)
263
+ for member in connected.members:
264
+ print(
265
+ f"sandbox={member.sandbox_id} "
266
+ f"private-ip={member.ip_address} "
267
+ f"status={member.status}"
268
+ )
269
+ finally:
270
+ sandbox.detach_network(network.id)
271
+ finally:
272
+ client.networks.delete(network.id)
273
+ ```
274
+
275
+ ## Lifecycle reads like the domain
276
+
277
+ ```python
278
+ sandbox.pause().wait_until_paused()
279
+
280
+ clone = sandbox.fork()
281
+ try:
282
+ sandbox.resume().wait_until_running()
283
+ finally:
284
+ clone.destroy()
285
+
286
+ sandbox.destroy()
287
+ ```
288
+
289
+ The `SandboxInstance` handle safely caches the latest server projection.
290
+ Lifecycle mutations and `refresh()` update it, while `id`, `name`, `status`,
291
+ `ip_address`, and `data` provide safe reads.
292
+
293
+ ## Errors stay inspectable
294
+
295
+ ```python
296
+ from createos import APIError, OperationTimeout
297
+
298
+
299
+ try:
300
+ sandbox.wait_until_running()
301
+ except APIError as error:
302
+ print(
303
+ f"HTTP {error.status_code}, code={error.code}, "
304
+ f"request={error.request_id}"
305
+ )
306
+ except OperationTimeout:
307
+ # A lifecycle or readiness wait exhausted its budget.
308
+ pass
309
+ ```
310
+
311
+ GET, HEAD, PUT, and DELETE requests are retried for transient network failures
312
+ and retryable server responses. HTTP 429 and 503 are retried for every method.
313
+ Configure the client with `RetryOptions`, or disable retries for one request
314
+ with `RequestOptions(disable_retry=True)`.
315
+
316
+ ## Examples
317
+
318
+ Runnable examples live under [`examples/`](examples/):
319
+
320
+ - [Hello world](examples/hello_world/README.md)
321
+ - [HTTP execution server](examples/execution_server/README.md)
322
+ - [Command streaming](examples/command_streaming/README.md)
323
+ - [Files and snapshots](examples/files_and_snapshots/README.md)
324
+ - [Ingress preview](examples/ingress_preview/README.md)
325
+ - [Private overlay network](examples/network/README.md)
326
+ - [Custom template](examples/custom_template/README.md)
327
+ - [Managed process lifecycle](examples/managed_process/README.md)
328
+ - [Desktop and noVNC](examples/desktop/README.md)
329
+
330
+ Together these examples cover command execution, file transfer, streaming,
331
+ ingress, snapshots, networking, templates, managed processes, and desktop use.
332
+
333
+ ## Development
334
+
335
+ Create a virtual environment and install the development dependencies:
336
+
337
+ ```sh
338
+ python -m venv .venv
339
+ .venv/bin/pip install -e '.[dev]'
340
+ ```
341
+
342
+ Run the same checks used while developing the SDK:
343
+
344
+ ```sh
345
+ .venv/bin/ruff format --check src tests examples
346
+ .venv/bin/ruff check src tests examples
347
+ .venv/bin/mypy src/createos --ignore-missing-imports
348
+ .venv/bin/pytest --cov=createos --cov-fail-under=70
349
+ ```
350
+
351
+ The project follows the
352
+ [Google Python Style Guide](https://google.github.io/styleguide/pyguide.html).
353
+ Formatting, import ordering, public docstrings, and static analysis are enforced
354
+ through the project configuration.
355
+
356
+ GitHub Actions runs these quality checks, tests Python 3.10 through 3.14, builds
357
+ both package distributions, and verifies that the generated wheel imports.
358
+
359
+ Commits follow Conventional Commits. See
360
+ [CONTRIBUTING.md](CONTRIBUTING.md) for accepted types, examples, and the checks
361
+ to run before opening a pull request.
362
+
363
+ ## Package layout
364
+
365
+ ```text
366
+ src/createos/client.py client configuration and account-level operations
367
+ src/createos/instance.py stateful sandbox lifecycle and command operations
368
+ src/createos/services.py files, processes, desktop, templates, disks, networks
369
+ src/createos/models.py public requests, responses, options, and enums
370
+ src/createos/_transport.py HTTP, authentication, retries, and JSend handling
371
+ src/createos/_streams.py NDJSON, SSE, command, process, and binary streams
372
+ examples/ runnable Python programs
373
+ tests/ mocked API contract tests
374
+ ```
375
+
376
+ ## About CreateOS
377
+
378
+ [CreateOS](https://createos.sh) is an execution and governance platform for AI
379
+ agents and applications. Learn more about isolated Firecracker-based workloads
380
+ on the [CreateOS Sandbox product page](https://createos.sh/products/sandbox).
381
+
382
+ ## License
383
+
384
+ This SDK is available under the [MIT License](LICENSE).