pydantic-ai-daytona
Daytona sandbox capability for Pydantic AI agents. DaytonaSandbox gives an agent an isolated cloud sandbox for running commands and working with files — a place to execute untrusted or model-generated code without touching the application host.
Installation
pip install pydantic-ai-daytona
Configuration
Get your API key from the Daytona Dashboard and set it in the environment (or a .env file):
export DAYTONA_API_KEY="your-daytona-api-key"
You can also pass api_key (plus optional api_url / target) directly to DaytonaSandbox.
Quickstart
from pydantic_ai import Agent
from pydantic_ai_daytona import DaytonaSandbox
agent = Agent(
'anthropic:claude-sonnet-4-6',
capabilities=[DaytonaSandbox()],
)
result = agent.run_sync('Write a Python script that prints the first 10 primes and run it.')
print(result.output)
By default every agent run gets a fresh sandbox, created from the Daytona default snapshot and deleted when the run ends.
The capability contributes four tools:
| Tool | Purpose |
|---|---|
run_command |
Run a shell command (pipes, redirection, and && work). |
read_file |
Read a UTF-8 text file (up to max_read_bytes); pageable with explicit offset/limit. |
write_file |
Write a UTF-8 text file, creating the parent directory. |
list_directory |
List directory entries, marking directories with /. |
Command output labels stdout and stderr separately, reports non-zero exit codes, and is truncated tail-first per stream, so errors and exit status remain visible. When a file read is cut short by the safety caps (or by limit), the result ends with the next offset to pass to continue reading — the model pages through large files the way grep -n numbers them.
Sandbox lifecycle
Owned (default) — each run creates a sandbox and deletes it when the run ends:
DaytonaSandbox(snapshot='my-snapshot') # or image='python:3.12-slim'
For fully untrusted code, block outbound network access at creation. Independently, ephemeral=True hardens cleanup: Daytona deletes the sandbox the moment it stops, even if your process crashed before its own cleanup ran.
DaytonaSandbox(network_block_all=True, ephemeral=True, labels={'app': 'support-agent'})
Attached — reuse a sandbox you manage elsewhere; it is started if stopped and never deleted:
DaytonaSandbox(sandbox_id='my-sandbox-id')
Injected session — share one sandbox across several runs while controlling its lifetime yourself:
from pydantic_ai_daytona import DaytonaSandbox, DaytonaSandboxSession
async def main():
async with DaytonaSandboxSession(snapshot='my-snapshot') as session:
agent = Agent('anthropic:claude-sonnet-4-6', capabilities=[DaytonaSandbox(session=session)])
await agent.run('Create /workspace/app.py with a hello-world FastAPI app.')
await agent.run('Now add a /health endpoint to the app you created.')
Configuration reference
| Parameter | Default | Description |
|---|---|---|
snapshot |
None |
Snapshot for owned sandboxes (None = Daytona default). |
image |
None |
Registry image for owned sandboxes (mutually exclusive with snapshot). |
sandbox_id |
None |
Attach to an existing sandbox instead of creating one. |
session |
None |
An entered DaytonaSandboxSession you own. |
env |
None |
Environment variables for owned sandboxes. |
workdir |
None |
Working directory for commands and relative file paths. |
labels |
None |
Labels attached to owned sandboxes (cost attribution, filtering). |
os_user |
None |
OS user commands run as in owned sandboxes. |
ephemeral |
None |
Delete an owned sandbox as soon as it stops. |
network_block_all |
None |
Block all outbound network access from owned sandboxes. |
network_allow_list |
None |
Comma-separated CIDRs owned sandboxes may reach. |
domain_allow_list |
None |
Comma-separated domains owned sandboxes may reach. |
auto_stop_interval |
None |
Minutes of inactivity before Daytona stops an owned sandbox. |
auto_delete_interval |
None |
Minutes after stopping before Daytona deletes an owned sandbox (0 = immediately, -1 = never). |
api_key |
None |
Daytona API key (falls back to DAYTONA_API_KEY). |
api_url |
None |
Daytona API URL (falls back to DAYTONA_API_URL). |
target |
None |
Daytona target region (falls back to DAYTONA_TARGET). |
default_command_timeout |
60.0 |
Seconds a command may run when the model omits timeout_seconds. |
max_command_timeout |
300 |
Hard ceiling in seconds for any single command. |
max_output_bytes |
51200 |
Byte cap per command output or file read. |
max_output_lines |
2000 |
Line cap per command output or file read. |
max_read_bytes |
5242880 |
Largest file read_file will read whole. |
instructions |
None |
Override the system-prompt instructions ('' disables them). |
Development
pip install -e ".[dev]"
pytest # unit tests (offline)
pytest tests/integration_tests # live tests (needs DAYTONA_API_KEY)
ruff check .
License
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pydantic_ai_daytona-0.1.0.tar.gz.
File metadata
- Download URL: pydantic_ai_daytona-0.1.0.tar.gz
- Upload date:
- Size: 22.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
57ef92e23189e6ef6786d2ae9fe873d4b797a5299f1217dadbc113a6cec26ff9
|
|
| MD5 |
b6ecd433296c17de1ffaa93898fcd08f
|
|
| BLAKE2b-256 |
7c1082d3df367f918a39a74d1d023b1a4098cf53d1122ddb50097aabe6b3a89f
|
Provenance
The following attestation bundles were made for pydantic_ai_daytona-0.1.0.tar.gz:
Publisher:
release.yml on daytona/integrations
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pydantic_ai_daytona-0.1.0.tar.gz -
Subject digest:
57ef92e23189e6ef6786d2ae9fe873d4b797a5299f1217dadbc113a6cec26ff9 - Sigstore transparency entry: 2437963476
- Sigstore integration time:
-
Permalink:
daytona/integrations@b04cd4c2e3a8ad40c1c1f2d5ccc3fcb8e27f00c3 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/daytona
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@b04cd4c2e3a8ad40c1c1f2d5ccc3fcb8e27f00c3 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pydantic_ai_daytona-0.1.0-py3-none-any.whl.
File metadata
- Download URL: pydantic_ai_daytona-0.1.0-py3-none-any.whl
- Upload date:
- Size: 23.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
34f13a0ede89100e9a3a2042d00d5085b3b3ae45f4ac550ee665501b1425b03f
|
|
| MD5 |
56af6a64386148b05fdce3a3ab587130
|
|
| BLAKE2b-256 |
8ba7acd692e560da7b2a7e190483a51d0f23ffd6b7b1feff79c26a314936bdf7
|
Provenance
The following attestation bundles were made for pydantic_ai_daytona-0.1.0-py3-none-any.whl:
Publisher:
release.yml on daytona/integrations
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pydantic_ai_daytona-0.1.0-py3-none-any.whl -
Subject digest:
34f13a0ede89100e9a3a2042d00d5085b3b3ae45f4ac550ee665501b1425b03f - Sigstore transparency entry: 2437963492
- Sigstore integration time:
-
Permalink:
daytona/integrations@b04cd4c2e3a8ad40c1c1f2d5ccc3fcb8e27f00c3 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/daytona
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@b04cd4c2e3a8ad40c1c1f2d5ccc3fcb8e27f00c3 -
Trigger Event:
push
-
Statement type: