Skip to content

Commit 26bc315

Browse files
chore: update readme (#34)
1 parent e1959a8 commit 26bc315

File tree

1 file changed

+253
-24
lines changed

1 file changed

+253
-24
lines changed

README.md

Lines changed: 253 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,283 @@
11
# Deno Sandbox Python SDK
22

3-
Create isolated [Deno sandboxes](https://deno.com/deploy/sandboxes) to run code
4-
in a lightweight Linux microVM. You can securely run shell scripts, spawn
5-
processes, execute JavaScript applications and REPLs, and interact with files
6-
remotely.
3+
The official Python SDK for [Deno Sandboxes](https://deno.com/deploy/sandboxes) - isolated, secure environments running in lightweight Linux microVMs. Create on-demand sandboxes to execute untrusted code, run shell commands, build AI agents with code execution capabilities, or provide interactive development environments.
74

8-
This Python SDK let's you create and manage sandboxes programmatically.
5+
## Key Features
6+
7+
- **Secure Isolation** - Each sandbox runs in its own microVM with full process and filesystem isolation
8+
- **Sync & Async APIs** - First-class support for both synchronous and asynchronous Python code
9+
- **Process Management** - Spawn and manage shell processes with full stdin/stdout/stderr control
10+
- **Deno Runtime** - Execute TypeScript/JavaScript code, run Deno scripts, or interact with a REPL
11+
- **Filesystem Operations** - Read, write, copy, and traverse files with a comprehensive filesystem API
12+
- **Persistent Storage** - Create volumes and snapshots to persist data across sandbox sessions
13+
- **App Management** - Create and manage Deno Deploy apps, revisions, and deployment timelines
14+
- **HTTP & SSH Exposure** - Expose sandbox services to the internet via HTTP or SSH
15+
- **Network Controls** - Fine-grained control over outbound network access with allowlists
16+
- **File Transfers** - Upload files from your local machine or download from the sandbox
17+
- **Configurable Resources** - Adjust memory limits, timeouts, and select deployment regions
918

1019
## Installation
1120

1221
```sh
13-
uv add deno-sandbox
14-
# or
1522
pip install deno-sandbox
1623
```
1724

25+
Or with [uv](https://docs.astral.sh/uv/):
26+
27+
```sh
28+
uv add deno-sandbox
29+
```
30+
31+
## Requirements
32+
33+
- Python 3.10+
34+
- A Deno Deploy access token (set as `DENO_DEPLOY_TOKEN` environment variable)
35+
1836
## Quick Start
1937

20-
Sync:
38+
### Synchronous API
2139

2240
```py
2341
from deno_sandbox import DenoDeploy
2442

25-
def main()
26-
sdk = DenoDeploy()
43+
sdk = DenoDeploy()
2744

28-
with sdk.sandbox.create() as sb
29-
child_process = sb.spawn("npx", args=["cowsay", "hello"])
30-
p.wait()
45+
with sdk.sandbox.create() as sb:
46+
# Run a shell command
47+
process = sb.spawn("echo", args=["Hello from the sandbox!"])
48+
process.wait()
3149

32-
if __name__ == "__main__"
33-
main()
50+
# Write and read files
51+
sb.fs.write_text_file("/tmp/example.txt", "Hello, World!")
52+
content = sb.fs.read_text_file("/tmp/example.txt")
53+
print(content)
3454
```
3555

36-
Async:
56+
### Asynchronous API
3757

3858
```py
59+
import asyncio
3960
from deno_sandbox import AsyncDenoDeploy
4061

41-
async def main()
42-
sdk = AsyncDenoDeploy()
62+
async def main():
63+
sdk = AsyncDenoDeploy()
64+
65+
async with sdk.sandbox.create() as sb:
66+
# Run a shell command
67+
process = await sb.spawn("echo", args=["Hello from the sandbox!"])
68+
await process.wait()
4369

44-
async with sdk.sandbox.create() as sb
45-
child_process = await sb.spawn("npx", args=["cowsay", "hello"])
46-
await p.wait()
70+
# Write and read files
71+
await sb.fs.write_text_file("/tmp/example.txt", "Hello, World!")
72+
content = await sb.fs.read_text_file("/tmp/example.txt")
73+
print(content)
4774

48-
if __name__ == "__main__"
49-
asyncio.run(main())
75+
asyncio.run(main())
5076
```
5177

78+
## Usage Examples
79+
80+
### Execute TypeScript/JavaScript with Deno
81+
82+
```py
83+
with sdk.sandbox.create() as sb:
84+
# Run inline TypeScript code
85+
result = sb.deno.eval("console.log('Hello from Deno!')")
86+
87+
# Or run a script file
88+
sb.fs.write_text_file("/app/server.ts", '''
89+
Deno.serve({ port: 8000 }, () => new Response("Hello!"));
90+
''')
91+
process = sb.deno.run(entrypoint="/app/server.ts")
92+
```
93+
94+
### Interactive Deno REPL
95+
96+
```py
97+
with sdk.sandbox.create() as sb:
98+
repl = sb.deno.repl()
99+
100+
# Evaluate expressions and get results
101+
result = repl.eval("1 + 1")
102+
print(result) # 2
103+
104+
result = repl.eval("const x = [1, 2, 3]; x.map(n => n * 2)")
105+
print(result) # [2, 4, 6]
106+
107+
repl.close()
108+
```
109+
110+
### Filesystem Operations
111+
112+
```py
113+
with sdk.sandbox.create() as sb:
114+
# Create directories
115+
sb.fs.mkdir("/app/data", recursive=True)
116+
117+
# Write files
118+
sb.fs.write_text_file("/app/data/config.json", '{"key": "value"}')
119+
sb.fs.write_file("/app/data/binary.bin", b"\x00\x01\x02\x03")
120+
121+
# Read files
122+
text = sb.fs.read_text_file("/app/data/config.json")
123+
binary = sb.fs.read_file("/app/data/binary.bin")
124+
125+
# List directory contents
126+
entries = sb.fs.read_dir("/app/data")
127+
for entry in entries:
128+
print(f"{entry['name']} - is_file: {entry['is_file']}")
129+
130+
# Walk directory tree
131+
for entry in sb.fs.walk("/app"):
132+
print(entry["path"])
133+
134+
# Glob pattern matching
135+
matches = sb.fs.expand_glob("**/*.json", root="/app")
136+
```
137+
138+
### Upload and Download Files
139+
140+
```py
141+
with sdk.sandbox.create() as sb:
142+
# Upload a local file or directory to the sandbox
143+
sb.fs.upload("./local/project", "/app/project")
144+
145+
# Run a build process
146+
process = sb.spawn("npm", args=["run", "build"], cwd="/app/project")
147+
process.wait()
148+
149+
# Download results
150+
sb.fs.download("./output", "/app/project/dist")
151+
```
152+
153+
### Persistent Volumes
154+
155+
```py
156+
# Create a volume for persistent storage
157+
volume = sdk.volumes.create(
158+
slug="my-data",
159+
region="us-east-1",
160+
capacity="1GB"
161+
)
162+
163+
# Use the volume in a sandbox
164+
with sdk.sandbox.create(volumes={"/data": volume["id"]}) as sb:
165+
sb.fs.write_text_file("/data/persistent.txt", "This data persists!")
166+
167+
# Create a snapshot of the volume
168+
snapshot = sdk.volumes.snapshot(volume["id"], slug="my-snapshot")
169+
```
170+
171+
### Expose HTTP Services
172+
173+
```py
174+
with sdk.sandbox.create() as sb:
175+
# Start a web server
176+
sb.fs.write_text_file("/app/server.ts", '''
177+
Deno.serve({ port: 8000 }, (req) => {
178+
return new Response("Hello from sandbox!");
179+
});
180+
''')
181+
process = sb.deno.run(entrypoint="/app/server.ts")
182+
process.wait_http_ready()
183+
184+
# Expose it publicly
185+
url = sb.expose_http(port=8000)
186+
print(f"Server available at: {url}")
187+
```
188+
189+
### Configure Sandbox Options
190+
191+
```py
192+
with sdk.sandbox.create(
193+
region="us-east-1", # Deploy region
194+
memory_mb=2048, # Memory limit (default: 1280 MB)
195+
timeout="5m", # Auto-shutdown timeout
196+
env={"NODE_ENV": "production"}, # Environment variables
197+
allow_net=["api.example.com"], # Network allowlist
198+
) as sb:
199+
process = sb.spawn("node", args=["app.js"])
200+
process.wait()
201+
```
202+
203+
### Manage Apps and Deployments
204+
205+
```py
206+
# Create a new app
207+
app = sdk.apps.create(slug="my-app")
208+
print(f"Created app: {app['slug']}")
209+
210+
# List all apps
211+
for app in sdk.apps.list():
212+
print(f"App: {app['slug']} (created: {app['created_at']})")
213+
214+
# Get revisions for an app
215+
revisions = sdk.revisions.list("my-app")
216+
for rev in revisions:
217+
print(f"Revision: {rev['id']} - Status: {rev['status']}")
218+
219+
# List timelines (deployment targets) for an app
220+
timelines = sdk.timelines.list("my-app")
221+
for timeline in timelines:
222+
print(f"Timeline: {timeline['slug']}")
223+
for domain in timeline["domains"]:
224+
print(f" Domain: {domain['domain']}")
225+
226+
# Update or delete an app
227+
sdk.apps.update("my-app", slug="renamed-app")
228+
sdk.apps.delete("renamed-app")
229+
```
230+
231+
## API Reference
232+
233+
### DenoDeploy / AsyncDenoDeploy
234+
235+
The main entry point for the SDK. Provides access to:
236+
237+
- `sandbox` - Create and manage sandbox instances
238+
- `volumes` - Create and manage persistent volumes
239+
- `snapshots` - List and manage volume snapshots
240+
- `apps` - Create and manage Deno Deploy applications
241+
- `revisions` - List and inspect app revisions
242+
- `timelines` - List deployment timelines and domains
243+
244+
### Sandbox
245+
246+
A running sandbox instance with:
247+
248+
- `spawn(command, args, ...)` - Spawn a child process
249+
- `fs` - Filesystem operations (read, write, mkdir, walk, etc.)
250+
- `deno` - Deno runtime (run scripts, REPL, eval)
251+
- `env` - Environment variable management
252+
- `expose_http(port)` - Expose HTTP service publicly
253+
- `expose_ssh()` - Expose SSH access
254+
- `fetch(url)` - Make HTTP requests from within the sandbox
255+
- `extend_timeout(seconds)` - Extend the sandbox timeout
256+
- `kill()` - Terminate the sandbox
257+
258+
### Apps
259+
260+
Manage Deno Deploy applications:
261+
262+
- `create(slug)` - Create a new app
263+
- `get(id_or_slug)` - Get app by ID or slug
264+
- `list()` - List all apps
265+
- `update(app, slug)` - Update an app
266+
- `delete(app)` - Delete an app
267+
268+
### Revisions
269+
270+
Track deployment revisions:
271+
272+
- `get(app, id)` - Get a specific revision
273+
- `list(app)` - List revisions for an app
274+
275+
### Timelines
276+
277+
Manage deployment timelines:
278+
279+
- `list(app)` - List timelines for an app (includes domains)
280+
52281
## License
53282

54-
`MIT`, see the [LICENSE file](./LICENSE)
283+
MIT - see the [LICENSE](./LICENSE) file for details.

0 commit comments

Comments
 (0)