File storage and sandbox backends for AI agents
Project description
Pydantic AI Backend
Sandboxed execution & file tools for agents.
A ready-made console toolset over State / Local / Docker / Daytona backends,
plus a sandbox service so your app never needs Docker access.
Docs · PyPI · Install · Ecosystem · Deep Agents
Console toolset • State / Local / Docker / Daytona / Remote • Permission system • Session manager • No docker-in-docker
Part of Pydantic Deep Agents — the open-source Claude Code alternative & Python agent framework. Use this library standalone, or get everything wired together in one
create_deep_agent()call.
Pydantic AI Backend gives your Pydantic AI agent everything it needs to read, write, and run code safely — a ready-made console toolset over in-memory, local-filesystem, or Docker-isolated backends, with a fine-grained permission system.
Use Cases
| What You Want to Build | How This Library Helps |
|---|---|
| AI Coding Assistant | Console toolset with file ops + code execution |
| Multi-User Web App | Docker sandboxes with session isolation |
| Code Review Bot | Read-only backend with grep/glob search |
| Secure Execution | Permission system blocks dangerous operations |
| Testing/CI | In-memory StateBackend for fast, isolated tests |
| Containerised SaaS | sandboxd owns Docker so your app container never holds the socket |
Installation
pip install pydantic-ai-backend
Or with uv:
uv add pydantic-ai-backend
Optional extras:
# Console toolset (requires pydantic-ai)
pip install pydantic-ai-backend[console]
# Docker sandbox support
pip install pydantic-ai-backend[docker]
# Remote sandboxes — client only needs httpx
pip install pydantic-ai-backend[remote]
# The sandbox service itself (install in the service image, not your app)
pip install pydantic-ai-backend[server]
# Everything
pip install pydantic-ai-backend[console,docker,remote]
Quick Start — ConsoleCapability (Recommended)
The simplest way to give your agent filesystem tools:
from pydantic_ai import Agent
from pydantic_ai_backends import ConsoleCapability
agent = Agent("openai:gpt-4.1", capabilities=[ConsoleCapability()])
With Permissions
from pydantic_ai_backends import ConsoleCapability
from pydantic_ai_backends.permissions import READONLY_RULESET
# Read-only agent — write/edit/execute tools are hidden from the model
agent = Agent("openai:gpt-4.1", capabilities=[ConsoleCapability(permissions=READONLY_RULESET)])
Alternative: Toolset API
from dataclasses import dataclass
from pydantic_ai import Agent
from pydantic_ai_backends import LocalBackend, create_console_toolset
@dataclass
class Deps:
backend: LocalBackend
agent = Agent(
"openai:gpt-4.1",
deps_type=Deps,
toolsets=[create_console_toolset()],
)
backend = LocalBackend(root_dir="./workspace")
result = agent.run_sync(
"Create a Python script that calculates fibonacci and run it",
deps=Deps(backend=backend),
)
print(result.output)
That's it. Your agent can now:
- List files and directories (
ls) - Read and write files (
read_file,write_file) - Edit files with string replacement (
edit_file) - Search with glob patterns and regex (
glob,grep) - Execute shell commands (
execute)
Available Backends
| Backend | Storage | Execution | Use Case |
|---|---|---|---|
StateBackend |
In-memory | No | Testing, ephemeral sessions |
LocalBackend |
Filesystem | Yes | Local development, CLI tools |
DockerSandbox |
Container | Yes | Multi-user, untrusted code |
RemoteSandbox |
Container, in another process | Yes | Containerised apps that must not hold the Docker socket |
CompositeBackend |
Routed | Varies | Complex multi-source setups |
In-Memory (StateBackend)
from pydantic_ai_backends import StateBackend
backend = StateBackend()
# Files stored in memory, perfect for tests
Local Filesystem (LocalBackend)
from pydantic_ai_backends import LocalBackend
backend = LocalBackend(
root_dir="/workspace",
allowed_directories=["/workspace", "/shared"],
enable_execute=True,
)
Docker Sandbox (DockerSandbox)
from pydantic_ai_backends import DockerSandbox
sandbox = DockerSandbox(runtime="python-datascience")
sandbox.start()
# Fully isolated container environment
sandbox.stop()
Reusable Named Container
from pydantic_ai_backends import DockerSandbox
# Named container persists between sessions (packages survive restarts)
sandbox = DockerSandbox(
image="python:3.12-slim",
container_name="my-dev-env", # implies auto_remove=False
volumes={"/my/project": "/workspace"},
)
# Next time: finds existing container and reattaches
Remote Sandbox (RemoteSandbox + sandboxd)
If your application runs in a container, giving it a Docker sandbox the obvious
way means mounting /var/run/docker.sock — which is an unauthenticated API for
root on the host. Docker-in-Docker needs --privileged and lands in the same
place. So instead, one small service owns the socket and your app speaks HTTP to
it:
from pydantic_ai_backends.remote import RemoteSandbox
sandbox = RemoteSandbox("http://sandboxd:8080", token="...", session_id="conv-42")
print(sandbox.execute("python -c 'print(1+1)'").output) # "2"
sandbox.stop()
Nothing starts until it is used: the session — and the container behind it — opens on the first operation, so an agent granted a sandbox it never touches costs no container and not even a round trip.
RemoteSandbox has the same synchronous surface as DockerSandbox, so it drops
into a console toolset or SessionManager unchanged. Failures degrade (b"",
[], Error: ...) instead of raising — a socket blip must not end an agent run.
The service is a few lines, and the client chooses nothing about the container:
from pydantic_ai_backends.remote.server import SandboxdConfig, create_app
app = create_app(
SandboxdConfig(
token="a-long-random-secret",
runtimes={"python": "python:3.12-slim"}, # allowlist; a request sends an alias
mem_limit="1g",
cpus=2.0,
network_mode="none", # sandboxes get no network by default
max_sessions=20, # beyond this: 429, not unbounded containers
workspace_root="/workspaces", # files survive idle reaping
)
)
services:
app:
environment: { SANDBOXD_URL: http://sandboxd:8080 }
networks: [backend] # no docker.sock here
sandboxd:
volumes: ["/var/run/docker.sock:/var/run/docker.sock"]
networks: [backend] # and no `ports:` either
Sessions can outlive the run that created them — pass reuse=True and the same
session_id to reattach on a later turn, so an agent keeps the files it wrote.
What the id keys on (a run, a chat, a user, an agent) is what decides who shares
the sandbox.
Three settings decide what survives an idle timeout, and they cover different
things: workspace_root keeps the work directory, persist_containers keeps
the container's write layer so pip install survives too, and
workspace_ttl reclaims workspaces nobody opens any more. stop(purge=True)
drops a session's files for good when its conversation is deleted.
Users can see what the agent wrote — including in a conversation from last week,
long after its sandbox was reaped. WorkspaceArchive reads the stored workspace
off the host volume, so no container starts:
from pydantic_ai_backends.remote import WorkspaceArchive
archive = WorkspaceArchive("http://sandboxd:8080", token="...")
for entry in archive.ls("conv-42"):
print(entry["path"], entry["size"])
print(archive.read("conv-42", "report.md"))
Proxy it from your backend rather than handing a token to the browser — a session
token authorizes execute too.
The operator dashboard
SandboxdConfig(ui_enabled=True) serves a dashboard at /ui — one
self-contained HTML file, no build step and no CDN, so it works offline and
behind a strict CSP. Three views:
Sessions — capacity at a glance, and every open session with its tenant, idle time and memory against its own ceiling.
Workspace — one session at full width: a terminal with command history, a file browser, the activity log and session info.
Runtimes & policy — the allowlist with each runtime's image, ceilings and whether it gets a network, the config that produces it, and every limit in force.
Off by default: the page asks a human for the service token, and that token can start containers on the host.
Console Toolset
Ready-to-use tools for pydantic-ai agents:
from pydantic_ai_backends import create_console_toolset
# All tools enabled
toolset = create_console_toolset()
# Without shell execution
toolset = create_console_toolset(include_execute=False)
# With approval requirements
toolset = create_console_toolset(
require_write_approval=True,
require_execute_approval=True,
)
# With custom tool descriptions
toolset = create_console_toolset(
descriptions={
"execute": "Run shell commands in the workspace",
"read_file": "Read file contents from the workspace",
}
)
Available tools: ls, read_file, write_file, edit_file, glob, grep, execute
Image Support
For multimodal models, enable image file handling:
toolset = create_console_toolset(image_support=True)
# Now read_file on .png/.jpg/.gif/.webp returns BinaryContent
# that multimodal models (GPT-4o, Claude, etc.) can see directly
Permission System
Fine-grained access control:
from pydantic_ai_backends import LocalBackend
from pydantic_ai_backends.permissions import DEFAULT_RULESET, READONLY_RULESET
# Safe defaults (allow reads, ask for writes)
backend = LocalBackend(root_dir="/workspace", permissions=DEFAULT_RULESET)
# Read-only mode
backend = LocalBackend(root_dir="/workspace", permissions=READONLY_RULESET)
| Preset | Description |
|---|---|
DEFAULT_RULESET |
Allow reads (except secrets), ask for writes/executes |
PERMISSIVE_RULESET |
Allow most operations, deny dangerous commands |
READONLY_RULESET |
Allow reads only, deny all writes and executes |
STRICT_RULESET |
Everything requires approval |
Docker Runtimes
Pre-configured environments:
| Runtime | Image | What it adds |
|---|---|---|
python-minimal |
python:3.12-slim | standard library only |
python-datascience |
built on python:3.12-slim | pandas, numpy, matplotlib, scikit-learn, seaborn |
python-analytics |
built on python:3.12-slim | duckdb, polars, pyarrow |
python-web |
built on python:3.12-slim | fastapi, uvicorn, sqlalchemy, httpx |
python-scraping |
built on python:3.12-slim | httpx, beautifulsoup4, lxml, markdownify |
python-documents |
built on python:3.12-slim | pypdf, python-docx, openpyxl, pillow |
node-minimal |
node:20-slim | nothing |
node-typescript |
built on node:20-slim | typescript, tsx, vitest |
node-react |
built on node:20-slim | typescript, vite, react, react-dom, @types/react |
bun |
oven/bun:1-slim | Bun's own bundler, test runner and package manager |
deno |
denoland/deno:alpine | TypeScript with no install step |
go |
golang:1.23-alpine | Go toolchain |
rust |
rust:1-slim | Rust toolchain with cargo |
A runtime naming an image starts as fast as a pull. One naming a base_image
plus packages builds an image on first use and hits the cache afterwards, which
is worth it when installing them per session would dominate.
Custom runtime:
from pydantic_ai_backends import DockerSandbox, RuntimeConfig
runtime = RuntimeConfig(
name="ml-env",
base_image="python:3.12-slim",
packages=["torch", "transformers"],
)
sandbox = DockerSandbox(runtime=runtime)
Session Manager
Multi-user web applications:
from pydantic_ai_backends import SessionManager
# Docker (default)
manager = SessionManager(
default_runtime="python-datascience",
workspace_root="/app/workspaces",
)
# Each user gets isolated sandbox
sandbox = await manager.get_or_create("user-123")
Custom Sandbox Factory
Use any sandbox backend (Daytona, custom, etc.):
from pydantic_ai_backends import SessionManager, DaytonaSandbox
def daytona_factory(session_id: str) -> DaytonaSandbox:
return DaytonaSandbox(sandbox_id=session_id)
manager = SessionManager(sandbox_factory=daytona_factory)
sandbox = await manager.get_or_create("user-123")
Why Choose This Library?
| Feature | Description |
|---|---|
| Multiple Backends | In-memory, filesystem, Docker, Daytona, Kubernetes, remote — same interface |
| Console Toolset | Ready-to-use tools for pydantic-ai agents |
| Permission System | Pattern-based access control with presets |
| Docker Isolation | Safe execution of untrusted code |
| No Docker-in-Docker | sandboxd holds the socket; your app holds a token |
| Session Management | Multi-user support with workspace persistence |
| Image Support | Multimodal models can see images via BinaryContent |
| Pre-built Runtimes | Python and Node.js environments ready to go |
Vstorm OSS Ecosystem
This library is one piece of a broader open-source toolkit for production AI agents — all built on Pydantic AI.
| Project | Description | Stars |
|---|---|---|
| Pydantic Deep Agents | The full agent framework and terminal assistant — bundles every library below into one create_deep_agent() call. |
|
| 👉 pydantic-ai-backend | Sandboxed execution & file tools — State / Local / Docker / Daytona backends + console toolset. | |
| subagents-pydantic-ai | Declarative multi-agent orchestration — sync / async / auto, with token tracking. | |
| summarization-pydantic-ai | Unlimited context for long-running agents — summarization or sliding window. | |
| pydantic-ai-shields | Drop-in guardrails — cost caps, prompt-injection defense, PII & secret redaction, tool blocking. | |
| pydantic-ai-todo | Task planning with subtasks, dependencies, and cycle detection. | |
| full-stack-ai-agent-template | Zero to production AI app in 30 minutes — FastAPI + Next.js 15, RAG, 6 AI frameworks. |
Want it all wired together? Pydantic Deep Agents ships every library above integrated — planning, filesystem, subagents, memory, context management, and guardrails — behind a single function call. Browse everything at oss.vstorm.co.
Contributing
git clone https://github.com/vstorm-co/pydantic-ai-backend.git
cd pydantic-ai-backend
make install
make test # 100% coverage required
Star History
If this library saved you from wiring an agent harness by hand — give it a ⭐. It's the single biggest thing that helps the project grow.
License
MIT — see LICENSE
Need help shipping AI agents in production?
We're Vstorm — an Applied Agentic AI Engineering Consultancy
with 30+ production agent implementations. Pydantic Deep Agents is what we build them with.
Made with care by Vstorm
Project details
Release history Release notifications | RSS feed
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_backend-0.2.17.tar.gz.
File metadata
- Download URL: pydantic_ai_backend-0.2.17.tar.gz
- Upload date:
- Size: 15.1 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7f8418e42034c97a7dfcca60b98cf19d8b4b26b643d124fd6eda0c2dd31c724d
|
|
| MD5 |
2c0629989e5f5dcc662057d0a11e1650
|
|
| BLAKE2b-256 |
08cf03ecc06835465b56348e71ca278edc7f88ff428b20a2b55832ddd4a5f23d
|
Provenance
The following attestation bundles were made for pydantic_ai_backend-0.2.17.tar.gz:
Publisher:
publish.yml on vstorm-co/pydantic-ai-backend
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pydantic_ai_backend-0.2.17.tar.gz -
Subject digest:
7f8418e42034c97a7dfcca60b98cf19d8b4b26b643d124fd6eda0c2dd31c724d - Sigstore transparency entry: 2308066736
- Sigstore integration time:
-
Permalink:
vstorm-co/pydantic-ai-backend@e195fbd7603ca64fb6a1fc6b833b0f1c14d26602 -
Branch / Tag:
refs/tags/0.2.17 - Owner: https://github.com/vstorm-co
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@e195fbd7603ca64fb6a1fc6b833b0f1c14d26602 -
Trigger Event:
release
-
Statement type:
File details
Details for the file pydantic_ai_backend-0.2.17-py3-none-any.whl.
File metadata
- Download URL: pydantic_ai_backend-0.2.17-py3-none-any.whl
- Upload date:
- Size: 163.5 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 |
47db81f1111ca1443c5cb051f0e7c6f955deff477097f22dc57aac70ab082fe3
|
|
| MD5 |
e08d112509f3f90d51cb11a67664e669
|
|
| BLAKE2b-256 |
2e3694206e0407524a93b8e42dc09966d31cfaa142f532405b731990e75ed7f6
|
Provenance
The following attestation bundles were made for pydantic_ai_backend-0.2.17-py3-none-any.whl:
Publisher:
publish.yml on vstorm-co/pydantic-ai-backend
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pydantic_ai_backend-0.2.17-py3-none-any.whl -
Subject digest:
47db81f1111ca1443c5cb051f0e7c6f955deff477097f22dc57aac70ab082fe3 - Sigstore transparency entry: 2308066794
- Sigstore integration time:
-
Permalink:
vstorm-co/pydantic-ai-backend@e195fbd7603ca64fb6a1fc6b833b0f1c14d26602 -
Branch / Tag:
refs/tags/0.2.17 - Owner: https://github.com/vstorm-co
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@e195fbd7603ca64fb6a1fc6b833b0f1c14d26602 -
Trigger Event:
release
-
Statement type: