deepagents-opensandbox 1.0.1__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,73 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - '*'
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ package-test:
13
+ runs-on: ubuntu-latest
14
+
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+
18
+ - uses: actions/setup-python@v5
19
+ with:
20
+ python-version: "3.11"
21
+
22
+ - name: Install uv
23
+ run: python -m pip install uv
24
+
25
+ - name: Run tests
26
+ run: |
27
+ uv sync
28
+ uv run --group dev pytest
29
+
30
+ release-build:
31
+ runs-on: ubuntu-latest
32
+
33
+ steps:
34
+ - uses: actions/checkout@v4
35
+
36
+ - uses: actions/setup-python@v5
37
+ with:
38
+ python-version: "3.11"
39
+
40
+ - name: Build release distributions
41
+ run: |
42
+ # NOTE: put your own distribution build steps here.
43
+ python -m pip install build
44
+ python -m build
45
+
46
+ - name: Upload distributions
47
+ uses: actions/upload-artifact@v4
48
+ with:
49
+ name: release-dists
50
+ path: dist/
51
+
52
+ pypi-publish:
53
+ runs-on: ubuntu-latest
54
+ needs:
55
+ - release-build
56
+ permissions:
57
+ id-token: write
58
+
59
+ environment:
60
+ name: pypi
61
+ url: https://pypi.org/p/opensandbox
62
+
63
+ steps:
64
+ - name: Retrieve release distributions
65
+ uses: actions/download-artifact@v4
66
+ with:
67
+ name: release-dists
68
+ path: dist/
69
+
70
+ - name: Publish release distributions to PyPI
71
+ uses: pypa/gh-action-pypi-publish@release/v1
72
+ with:
73
+ packages-dir: dist/
@@ -0,0 +1,112 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ env/
12
+ build/
13
+ develop-eggs/
14
+ dist/
15
+ downloads/
16
+ eggs/
17
+ .eggs/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ *.egg-info/
24
+ .installed.cfg
25
+ *.egg
26
+
27
+ # PyInstaller
28
+ # Usually these files are written by a python script from a template
29
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
30
+ *.manifest
31
+ *.spec
32
+
33
+ # Installer logs
34
+ pip-log.txt
35
+ pip-delete-this-directory.txt
36
+
37
+ # Unit test / coverage reports
38
+ htmlcov/
39
+ .tox/
40
+ .coverage
41
+ .coverage.*
42
+ .cache
43
+ nosetests.xml
44
+ coverage.xml
45
+ *.cover
46
+ .hypothesis/
47
+
48
+ # Translations
49
+ *.mo
50
+ *.pot
51
+
52
+ # Django stuff:
53
+ *.log
54
+ local_settings.py
55
+
56
+ # Flask stuff:
57
+ instance/
58
+ .webassets-cache
59
+
60
+ # Scrapy stuff:
61
+ .scrapy
62
+
63
+ # Sphinx documentation
64
+ docs/_build/
65
+
66
+ # PyBuilder
67
+ target/
68
+
69
+ # Jupyter Notebook
70
+ .ipynb_checkpoints
71
+
72
+ # pyenv
73
+ .python-version
74
+
75
+ # celery beat schedule file
76
+ celerybeat-schedule
77
+
78
+ # SageMath parsed files
79
+ *.sage.py
80
+
81
+ # dotenv
82
+ .env
83
+
84
+ # virtualenv
85
+ .venv
86
+ venv/
87
+ ENV/
88
+
89
+ # Spyder project settings
90
+ .spyderproject
91
+ .spyproject
92
+
93
+ # Rope project settings
94
+ .ropeproject
95
+
96
+ # mkdocs documentation
97
+ /site
98
+
99
+ # mypy
100
+ .mypy_cache/
101
+
102
+ # this package
103
+ .idea/
104
+ .vscode/
105
+ .cursor/
106
+ .claude/
107
+ .codex/
108
+ .pytest_cache/
109
+ .DS_Store
110
+ *.pyc
111
+ *.swp
112
+ *.whl
@@ -0,0 +1,70 @@
1
+ # AGENTS.md
2
+
3
+ ## Project Overview
4
+ `deepagents-opensandbox` is a Python package that implements a sandbox backend for the [DeepAgents](https://github.com/shkarupa-alex/deepagents) framework using [OpenSandbox](https://github.com/alibaba/OpenSandbox). It allows DeepAgents to execute code and commands in isolated OpenSandbox environments.
5
+
6
+ - **Language**: Python 3.11+
7
+ - **Dependency Manager**: `uv`
8
+
9
+ ## Project Structure
10
+
11
+ ```
12
+ deepagents-opensandbox/
13
+ ├── deepagents_opensandbox/
14
+ │ ├── __init__.py # Package exports
15
+ │ ├── backend.py # OpensandboxBackend implementation
16
+ │ ├── provider.py # OpensandboxProvider implementation
17
+ │ ├── conftest.py # Shared test fixtures
18
+ │ ├── backend_test.py # Backend unit and integration tests
19
+ │ └── provider_test.py # Provider unit and integration tests
20
+ ├── pyproject.toml # Project configuration and dependencies
21
+ ├── uv.lock # Dependency lock file
22
+ ├── docker-compose.yaml # Local dev server (OpenSandbox in Docker)
23
+ └── AGENTS.md # Documentation for AI coding agents
24
+ ```
25
+
26
+ ## Architecture
27
+
28
+ ### 1. `OpensandboxBackend` (`backend.py`)
29
+ - Inherits from `BaseSandbox` from `deepagents.backends.sandbox`.
30
+ - Wraps `SandboxSync` for execute/upload/download.
31
+ - Command execution via `sandbox.commands.run()` + `sandbox.commands.get_command_status()`.
32
+ - File upload via `sandbox.files.write_file()`, download via `sandbox.files.read_bytes()`.
33
+
34
+ ### 2. `OpensandboxProvider` (`provider.py`)
35
+ - Inherits from `SandboxProvider` from `deepagents_cli.integrations.sandbox_provider`.
36
+ - Lifecycle management: create, connect, delete (sync + async).
37
+ - Async path (`aget_or_create`) uses native async SDK (`Sandbox`) for non-blocking creation, then wraps in sync `SandboxSync` backend.
38
+ - Configuration via env vars: `OPEN_SANDBOX_API_KEY`, `OPEN_SANDBOX_DOMAIN`.
39
+
40
+ ## Commands
41
+
42
+ - **Unit tests**: `uv run python -m pytest deepagents_opensandbox/ -v -k "not integration"`
43
+ - **Integration tests**: `OPEN_SANDBOX_DOMAIN=localhost:8090 uv run python -m pytest deepagents_opensandbox/ -v -k integration`
44
+ - **All tests**: `OPEN_SANDBOX_DOMAIN=localhost:8090 uv run python -m pytest deepagents_opensandbox/ -v`
45
+ - **Lint**: `uv run ruff check deepagents_opensandbox/`
46
+ - **Format check**: `uv run ruff format --check deepagents_opensandbox/`
47
+
48
+ ## Server proxy mode
49
+
50
+ The SDK can talk to sandbox containers in two ways:
51
+
52
+ 1. **Direct** (`use_server_proxy=False`, default): SDK connects to container IP/port directly. Works when client and containers are on the same network.
53
+ 2. **Server proxy** (`use_server_proxy=True`): All execd requests go through the OpenSandbox server at `OPEN_SANDBOX_DOMAIN`. Required when the client cannot reach container IPs (e.g. server in Docker, client on host — `host.docker.internal` is not resolvable from macOS host).
54
+
55
+ `use_server_proxy` defaults to `False` in `OpensandboxProvider`. Integration tests pass `True` explicitly because they run from the host against a Docker-based server. Our docker-compose setup runs the server in Docker with `host_ip = "host.docker.internal"`.
56
+
57
+ ## Known issues
58
+
59
+ - **Server ≤ v0.1.4**: proxy handler in `lifecycle.py` drops query parameters on GET requests (builds `target_url` without `request.url.query`). File downloads via proxy return `400 MISSING_QUERY`. Fixed in `main` (not yet released). Workaround: build server image from source. Our docker-compose uses a locally-built image with this fix.
60
+
61
+ ## Development Standards
62
+
63
+ ### Code Style
64
+ - **Formatter/Linter**: `ruff` (configuration in `pyproject.toml`).
65
+ - **Type Hints**: Strict typing enforced.
66
+ - **Docstrings**: Google-style for public APIs.
67
+
68
+ ### Testing
69
+ - Tests are in `*_test.py` files alongside source code.
70
+ - Integration tests are gated by `OPEN_SANDBOX_DOMAIN` env var and a TCP connectivity check (`integration_server_available()` in `conftest.py`).
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Shkarupa Alex
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,132 @@
1
+ Metadata-Version: 2.4
2
+ Name: deepagents-opensandbox
3
+ Version: 1.0.1
4
+ Summary: Opensandbox backend for DeepAgents
5
+ License-File: LICENSE
6
+ Requires-Python: >=3.11
7
+ Requires-Dist: deepagents>=0.4.5
8
+ Requires-Dist: opensandbox>=0.1.5
9
+ Provides-Extra: cli
10
+ Requires-Dist: deepagents-cli>=0.0.27; extra == 'cli'
11
+ Description-Content-Type: text/markdown
12
+
13
+ # deepagents-opensandbox
14
+
15
+ OpenSandbox backend for the [DeepAgents](https://github.com/shkarupa-alex/deepagents) framework. This package enables DeepAgents to launch and control isolated sandbox environments using [OpenSandbox](https://github.com/nicholasgriffintn/OpenSandbox).
16
+
17
+ ## Key Features
18
+
19
+ - **Sandbox Provider**: Manages the lifecycle of OpenSandbox instances (create, connect, delete) via the `SandboxProvider` interface from `deepagents-cli`.
20
+ - **Sandbox Backend**: Provides a standard interface for command execution and file operations within a sandbox using the synchronous OpenSandbox SDK (`SandboxSync`).
21
+ - **DeepAgents Integration**: Fully compatible with `BaseSandbox` and `SandboxProvider` interfaces.
22
+
23
+ ## Installation
24
+
25
+ ```bash
26
+ pip install deepagents-opensandbox
27
+ ```
28
+
29
+ ## Usage
30
+
31
+ ```python
32
+ from deepagents_opensandbox import OpensandboxProvider
33
+
34
+ # Initialize the provider (uses OPEN_SANDBOX_API_KEY and OPEN_SANDBOX_DOMAIN env vars)
35
+ provider = OpensandboxProvider()
36
+
37
+ # Create a new sandbox
38
+ sandbox = provider.get_or_create(image="python:3.11")
39
+
40
+ # Execute a command
41
+ result = sandbox.execute("echo 'Hello World'")
42
+ print(result.output)
43
+
44
+ # Clean up
45
+ provider.delete(sandbox_id=sandbox.id)
46
+ ```
47
+
48
+ ### Using the backend directly
49
+
50
+ ```python
51
+ from opensandbox.sync.sandbox import SandboxSync
52
+ from deepagents_opensandbox import OpensandboxBackend
53
+
54
+ sandbox = SandboxSync.create("python:3.11")
55
+ backend = OpensandboxBackend(sandbox=sandbox)
56
+
57
+ result = backend.execute("python --version")
58
+ print(result.output)
59
+
60
+ sandbox.kill()
61
+ sandbox.close()
62
+ ```
63
+
64
+ ## Configuration
65
+
66
+ | Environment Variable | Description | Default |
67
+ |---------------------------|--------------------------------------|------------------|
68
+ | `OPEN_SANDBOX_API_KEY` | API key for authentication | *(none)* |
69
+ | `OPEN_SANDBOX_DOMAIN` | OpenSandbox server domain | `localhost:8080` |
70
+
71
+ ### Server proxy mode
72
+
73
+ By default, the SDK connects directly to sandbox container IPs. This works when the client and sandbox containers share the same network (e.g. both on the host, or in the same Docker/Kubernetes network).
74
+
75
+ When the OpenSandbox **server runs inside Docker** and the client runs on the **host machine**, container IPs (like `host.docker.internal`) are not reachable from the host. In this case, enable server proxy mode so that all execd requests are routed through the server:
76
+
77
+ ```python
78
+ provider = OpensandboxProvider(use_server_proxy=True)
79
+ ```
80
+
81
+ | Deployment | `use_server_proxy` |
82
+ |-----------------------------------------|--------------------|
83
+ | Server native on host, client on host | `False` (default) |
84
+ | Server in Docker, client on host | `True` |
85
+ | Server in Docker, client in same network| `False` |
86
+ | Kubernetes with proper networking | `False` |
87
+
88
+ > **Note:** OpenSandbox server `v0.1.4` and earlier have a [bug](https://github.com/alibaba/OpenSandbox) where the proxy handler drops query parameters on GET requests, causing file downloads to fail with `400 MISSING_QUERY`. The fix is merged into `main` but not yet released. If you hit this issue, build the server image from source (`server/` directory).
89
+
90
+ ## Development
91
+
92
+ This project uses `uv` for dependency management.
93
+
94
+ ### Prerequisites
95
+
96
+ - [uv](https://github.com/astral-sh/uv) installed.
97
+ - Python 3.11 or higher.
98
+
99
+ ### Setup
100
+
101
+ Install dependencies:
102
+
103
+ ```bash
104
+ uv sync
105
+ ```
106
+
107
+ ### Testing
108
+
109
+ Tests are split into unit tests (mocked) and integration tests (requiring a real server).
110
+
111
+ **Run Unit Tests (Mocked)**
112
+
113
+ These tests mock the OpenSandbox SDK calls and do not require a running server.
114
+
115
+ ```bash
116
+ uv run python -m pytest deepagents_opensandbox/ -v
117
+ ```
118
+
119
+ **Run Integration Tests**
120
+
121
+ These tests verify behavior against a real OpenSandbox server. They use `use_server_proxy=True` since the test runner is on the host while the server is in Docker.
122
+
123
+ ```bash
124
+ OPEN_SANDBOX_DOMAIN=localhost:8090 uv run python -m pytest deepagents_opensandbox/ -v -k integration
125
+ ```
126
+
127
+ ### Linting
128
+
129
+ ```bash
130
+ uv run ruff check deepagents_opensandbox/
131
+ uv run ruff format --check deepagents_opensandbox/
132
+ ```
@@ -0,0 +1,120 @@
1
+ # deepagents-opensandbox
2
+
3
+ OpenSandbox backend for the [DeepAgents](https://github.com/shkarupa-alex/deepagents) framework. This package enables DeepAgents to launch and control isolated sandbox environments using [OpenSandbox](https://github.com/nicholasgriffintn/OpenSandbox).
4
+
5
+ ## Key Features
6
+
7
+ - **Sandbox Provider**: Manages the lifecycle of OpenSandbox instances (create, connect, delete) via the `SandboxProvider` interface from `deepagents-cli`.
8
+ - **Sandbox Backend**: Provides a standard interface for command execution and file operations within a sandbox using the synchronous OpenSandbox SDK (`SandboxSync`).
9
+ - **DeepAgents Integration**: Fully compatible with `BaseSandbox` and `SandboxProvider` interfaces.
10
+
11
+ ## Installation
12
+
13
+ ```bash
14
+ pip install deepagents-opensandbox
15
+ ```
16
+
17
+ ## Usage
18
+
19
+ ```python
20
+ from deepagents_opensandbox import OpensandboxProvider
21
+
22
+ # Initialize the provider (uses OPEN_SANDBOX_API_KEY and OPEN_SANDBOX_DOMAIN env vars)
23
+ provider = OpensandboxProvider()
24
+
25
+ # Create a new sandbox
26
+ sandbox = provider.get_or_create(image="python:3.11")
27
+
28
+ # Execute a command
29
+ result = sandbox.execute("echo 'Hello World'")
30
+ print(result.output)
31
+
32
+ # Clean up
33
+ provider.delete(sandbox_id=sandbox.id)
34
+ ```
35
+
36
+ ### Using the backend directly
37
+
38
+ ```python
39
+ from opensandbox.sync.sandbox import SandboxSync
40
+ from deepagents_opensandbox import OpensandboxBackend
41
+
42
+ sandbox = SandboxSync.create("python:3.11")
43
+ backend = OpensandboxBackend(sandbox=sandbox)
44
+
45
+ result = backend.execute("python --version")
46
+ print(result.output)
47
+
48
+ sandbox.kill()
49
+ sandbox.close()
50
+ ```
51
+
52
+ ## Configuration
53
+
54
+ | Environment Variable | Description | Default |
55
+ |---------------------------|--------------------------------------|------------------|
56
+ | `OPEN_SANDBOX_API_KEY` | API key for authentication | *(none)* |
57
+ | `OPEN_SANDBOX_DOMAIN` | OpenSandbox server domain | `localhost:8080` |
58
+
59
+ ### Server proxy mode
60
+
61
+ By default, the SDK connects directly to sandbox container IPs. This works when the client and sandbox containers share the same network (e.g. both on the host, or in the same Docker/Kubernetes network).
62
+
63
+ When the OpenSandbox **server runs inside Docker** and the client runs on the **host machine**, container IPs (like `host.docker.internal`) are not reachable from the host. In this case, enable server proxy mode so that all execd requests are routed through the server:
64
+
65
+ ```python
66
+ provider = OpensandboxProvider(use_server_proxy=True)
67
+ ```
68
+
69
+ | Deployment | `use_server_proxy` |
70
+ |-----------------------------------------|--------------------|
71
+ | Server native on host, client on host | `False` (default) |
72
+ | Server in Docker, client on host | `True` |
73
+ | Server in Docker, client in same network| `False` |
74
+ | Kubernetes with proper networking | `False` |
75
+
76
+ > **Note:** OpenSandbox server `v0.1.4` and earlier have a [bug](https://github.com/alibaba/OpenSandbox) where the proxy handler drops query parameters on GET requests, causing file downloads to fail with `400 MISSING_QUERY`. The fix is merged into `main` but not yet released. If you hit this issue, build the server image from source (`server/` directory).
77
+
78
+ ## Development
79
+
80
+ This project uses `uv` for dependency management.
81
+
82
+ ### Prerequisites
83
+
84
+ - [uv](https://github.com/astral-sh/uv) installed.
85
+ - Python 3.11 or higher.
86
+
87
+ ### Setup
88
+
89
+ Install dependencies:
90
+
91
+ ```bash
92
+ uv sync
93
+ ```
94
+
95
+ ### Testing
96
+
97
+ Tests are split into unit tests (mocked) and integration tests (requiring a real server).
98
+
99
+ **Run Unit Tests (Mocked)**
100
+
101
+ These tests mock the OpenSandbox SDK calls and do not require a running server.
102
+
103
+ ```bash
104
+ uv run python -m pytest deepagents_opensandbox/ -v
105
+ ```
106
+
107
+ **Run Integration Tests**
108
+
109
+ These tests verify behavior against a real OpenSandbox server. They use `use_server_proxy=True` since the test runner is on the host while the server is in Docker.
110
+
111
+ ```bash
112
+ OPEN_SANDBOX_DOMAIN=localhost:8090 uv run python -m pytest deepagents_opensandbox/ -v -k integration
113
+ ```
114
+
115
+ ### Linting
116
+
117
+ ```bash
118
+ uv run ruff check deepagents_opensandbox/
119
+ uv run ruff format --check deepagents_opensandbox/
120
+ ```
@@ -0,0 +1,27 @@
1
+ """Opensandbox integration for DeepAgents.
2
+
3
+ This package provides:
4
+ - OpensandboxBackend: Sandbox backend for executing commands in OpenSandbox containers
5
+ - OpensandboxProvider: Provider for managing OpenSandbox lifecycle (requires ``deepagents-cli``)
6
+
7
+ Example usage:
8
+ ```python
9
+ from deepagents_opensandbox import OpensandboxProvider
10
+
11
+ provider = OpensandboxProvider()
12
+ sandbox = provider.get_or_create(image="python:3.11")
13
+ result = sandbox.execute("echo 'Hello'")
14
+ provider.delete(sandbox_id=sandbox.id)
15
+ ```
16
+ """
17
+
18
+ from deepagents_opensandbox.backend import OpensandboxBackend
19
+
20
+ __all__ = ["OpensandboxBackend"]
21
+
22
+ try:
23
+ from deepagents_opensandbox.provider import OpensandboxProvider
24
+
25
+ __all__ += ["OpensandboxProvider"] # type: ignore[assignment]
26
+ except ImportError:
27
+ pass