A lightweight, secure sandbox runtime for AI Agents
Project description
Self-hosted. Pluggable. Agent-ready.
doka is a lightweight sandbox runtime for AI Agents — like E2B, but self-hosted and runtime-pluggable. It gives developers a simple programmable environment for running commands, moving files, and managing isolated execution without forcing them into a specific Agent framework.
Agents are hard to standardize. Commands are not. doka focuses on the universal primitive every Agent eventually needs: a safe place to run code.
Core Features
Minimalist API
No servers, no orchestration boilerplate, no Agent-specific adapter required:
from doka import Sandbox
with Sandbox() as sandbox:
result = sandbox.commands.run('echo "Hello from Doka Sandbox!"')
print(result.stdout)
Write files, execute scripts, and read outputs from the sandbox:
from doka import Sandbox
with Sandbox() as sandbox:
sandbox.files.write("/tmp/agent.py", "print('Hello from an agent script')\n")
result = sandbox.commands.run("python /tmp/agent.py")
print(result.stdout)
Command-first Agent Runtime
doka does not try to guess how your Agent should start.
LangChain, AutoGen, CrewAI, custom scripts, shell workflows, compiled binaries — every Agent has a different lifecycle. Instead of forcing an Agent abstraction, doka gives you an isolated machine-like environment and lets you run whatever command makes sense.
with Sandbox() as sandbox:
sandbox.files.write("/workspace/main.py", agent_code)
result = sandbox.commands.run("python /workspace/main.py")
File I/O Built In
Move data in and out of the sandbox without exposing Docker internals:
with Sandbox() as sandbox:
sandbox.files.write("/tmp/input.txt", "hello")
sandbox.commands.run("cat /tmp/input.txt > /tmp/output.txt")
output = sandbox.files.read("/tmp/output.txt")
Resource Controls
Limit CPU, memory, network, and filesystem behavior with a small configuration object:
from doka import Limits, Sandbox
limits = Limits(
cpu="1.0",
memory="512m",
timeout=60,
network=False,
fs_readonly=False,
)
with Sandbox(limits=limits) as sandbox:
result = sandbox.commands.run("python agent.py")
Pluggable Runtime Backends
doka starts with Docker for local development and quick iteration, while keeping the runtime layer open for stronger isolation backends.
| Runtime | Status | Isolation | Best for |
|---|---|---|---|
| Docker | Available | Container isolation | Local development, trusted code |
| gVisor | Planned | Userspace kernel sandbox | Production Agent workloads |
| Kata Containers | Planned | Lightweight VM isolation | High-security workloads |
The public API stays the same while the backend changes:
with Sandbox(runtime="docker") as sandbox:
sandbox.commands.run("python agent.py")
# Future:
# with Sandbox(runtime="gvisor") as sandbox:
# sandbox.commands.run("python agent.py")
Quick Start
Requirements
- Python 3.10+
- Docker Desktop or Docker Engine
- Linux containers enabled when running on Windows
Installation
From PyPI after release:
pip install dokapy
For local development:
pip install -e .
Run a Sandbox Command
from doka import Sandbox
with Sandbox() as sandbox:
result = sandbox.commands.run('echo "Hello from Doka!"')
print(result.stdout)
Run an Agent Script
from doka import Sandbox
agent_code = """
print('Agent started')
print('Agent finished')
"""
with Sandbox() as sandbox:
sandbox.files.write("/tmp/agent.py", agent_code)
result = sandbox.commands.run("python /tmp/agent.py")
print(result.stdout)
Local Demo
A temporary Docker demo is available in playground/docker_demo.py.
python playground/docker_demo.py
API Reference
Sandbox(runtime="docker", limits=None, image=None)
Creates an isolated sandbox environment.
| Parameter | Type | Default | Description |
|---|---|---|---|
| runtime | str | "docker" |
Runtime backend. Currently supports "docker". |
| limits | Limits | None | None |
Resource limits for the sandbox. |
| image | str | None | None |
Container image. Defaults to python:3.11-slim for Docker. |
Recommended usage:
with Sandbox() as sandbox:
result = sandbox.commands.run("python --version")
Manual lifecycle:
sandbox = Sandbox().start()
try:
result = sandbox.commands.run("python --version")
finally:
sandbox.close()
sandbox.commands.run(command, background=False, env=None, workdir=None)
Executes a command inside the sandbox.
| Parameter | Type | Default | Description |
|---|---|---|---|
| command | str | required | Shell command to execute. |
| background | bool | False |
Run as a background process when True. |
| env | dict | None | None |
Additional environment variables. |
| workdir | str | None | None |
Working directory inside the sandbox. |
Blocking mode returns CommandResult:
result = sandbox.commands.run("python --version")
print(result.stdout)
print(result.stderr)
print(result.exit_code)
Background mode returns Process:
process = sandbox.commands.run("python long_running_agent.py", background=True)
for chunk in process.stdout.stream():
print(chunk)
exit_code = process.wait()
sandbox.files
Simple file operations inside the sandbox.
| Method | Description |
|---|---|
write(path, content) |
Write text content to a file inside the sandbox. |
read(path) |
Read a file from inside the sandbox. |
exists(path) |
Return whether a path exists inside the sandbox. |
sandbox.files.write("/tmp/input.txt", "hello")
exists = sandbox.files.exists("/tmp/input.txt")
content = sandbox.files.read("/tmp/input.txt")
Limits
Resource constraints for the sandbox.
| Field | Type | Default | Description |
|---|---|---|---|
| cpu | str | "1.0" |
CPU quota, e.g. "0.5", "1.0", "2.0". |
| memory | str | "512m" |
Memory limit, e.g. "512m", "1g". |
| timeout | int | None | None |
Command timeout in seconds. |
| network | bool | True |
Whether network access is allowed. |
| fs_readonly | bool | False |
Whether the root filesystem is read-only. |
Why doka?
AI Agents need execution environments, not another framework-specific wrapper.
doka gives you the minimum useful abstraction:
sandbox = Sandbox()
result = sandbox.commands.run("your command here")
Everything else — which Agent framework to use, how to start it, what files it needs, what it outputs — stays under developer control.
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 dokapy-0.1.0.tar.gz.
File metadata
- Download URL: dokapy-0.1.0.tar.gz
- Upload date:
- Size: 11.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
66d03e8c215f7eec4062da5a73c3e04040af6d0010a9ba5aad8f71d50a208669
|
|
| MD5 |
56b47c1b7bbbabc5eb7a7b7bf0ff8c23
|
|
| BLAKE2b-256 |
0b9c62f8372036501915b771d2474d640581c09f2d57ef93532fb7ad9b66e8e7
|
Provenance
The following attestation bundles were made for dokapy-0.1.0.tar.gz:
Publisher:
publish.yml on zhixiangxue/doka-ai
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dokapy-0.1.0.tar.gz -
Subject digest:
66d03e8c215f7eec4062da5a73c3e04040af6d0010a9ba5aad8f71d50a208669 - Sigstore transparency entry: 1401931551
- Sigstore integration time:
-
Permalink:
zhixiangxue/doka-ai@7602fe354d55d4a7ee47030b3d364dba4c180612 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/zhixiangxue
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@7602fe354d55d4a7ee47030b3d364dba4c180612 -
Trigger Event:
release
-
Statement type:
File details
Details for the file dokapy-0.1.0-py3-none-any.whl.
File metadata
- Download URL: dokapy-0.1.0-py3-none-any.whl
- Upload date:
- Size: 12.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3375c98db3225ab412d8932691b4e2223424977156b0fbd164cd0ad2f94f25dc
|
|
| MD5 |
c6343df2c2f48c336809a2f6248dd7af
|
|
| BLAKE2b-256 |
8a4c9e3135671c60e5069ca7e3c8023e5d66c59ca1937531d12ec6c57a1927d0
|
Provenance
The following attestation bundles were made for dokapy-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on zhixiangxue/doka-ai
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dokapy-0.1.0-py3-none-any.whl -
Subject digest:
3375c98db3225ab412d8932691b4e2223424977156b0fbd164cd0ad2f94f25dc - Sigstore transparency entry: 1401931601
- Sigstore integration time:
-
Permalink:
zhixiangxue/doka-ai@7602fe354d55d4a7ee47030b3d364dba4c180612 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/zhixiangxue
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@7602fe354d55d4a7ee47030b3d364dba4c180612 -
Trigger Event:
release
-
Statement type: