Guardrailed Python execution runner with subprocess isolation, timeout, memory caps, and import/global controls
Project description
safe-py-runner
A lightweight Python code runner with guardrails for LLM agent workflows.
Why This Package
When building agents that execute generated Python code, you often choose between:
- Running code directly in your process (
exec) - risky. - Full container sandboxing - heavier and slower.
- External sandbox APIs - added cost and latency.
safe-py-runner provides a practical middle path:
- subprocess isolation
- timeout enforcement
- memory limits (POSIX; macOS enforcement can be weaker than Linux)
- import/builtin policy restrictions
- JSON-safe input/output handling
Honest scope:
- Good fit: LLM-generated scripts for your own team and other controlled internal workloads.
- Not good alone: anonymous public code execution. Use Docker/VM/OS sandboxing as the primary boundary.
Where It Fits
| Option | Isolation Strength | Operational Cost | Typical Use |
|---|---|---|---|
eval / exec in main process |
Low | Low | Local scripts, trusted experiments |
safe-py-runner |
Medium | Low to medium | Internal tools, agent prototypes, controlled workloads |
| Docker / VM / E2B-style sandbox | High | Medium to high | Production multi-tenant or hostile untrusted code |
Production guidance:
- For hostile public-user code, use Docker/VM/external sandboxing as the primary boundary.
safe-py-runnercan be used as an extra inner guardrail layer.
It supports two policy modes:
restrict(default): block selected symbols.allow: allow only selected symbols.
Backends
The API now uses explicit engine objects through run_code(..., engine=...).
LocalEngine: host subprocess execution in managed venv.DockerEngine: managed Docker container execution.
If DockerEngine is used but Docker is unavailable, execution fails with a clear error.
DockerEngine can also target remote daemons with docker_context or SSH options.
Docker installation:
- Docker Desktop (macOS/Windows): https://www.docker.com/products/docker-desktop/
- Docker Engine docs (Linux): https://docs.docker.com/engine/install/
For production workloads, prefer DockerEngine over LocalEngine.
Installation
pip install safe-py-runner
Quick Start
from safe_py_runner import LocalEngine, RunnerPolicy, run_code
policy = RunnerPolicy(
timeout_seconds=5,
memory_limit_mb=128,
blocked_imports=["os", "subprocess", "socket"],
)
engine = LocalEngine(venv_dir="/tmp/safe_py_runner_pypi_demo")
result = run_code(
code="import math\nresult = math.sqrt(input_data['x'])",
input_data={"x": 81},
policy=policy,
engine=engine,
)
# Or load policy from a TOML config file
result = run_code(
code="result = 1 + 1",
policy_file="/absolute/path/to/policy.toml",
engine=engine,
)
if result.ok:
print(result.result) # 9.0
else:
print(result.error)
Security Note
This is not an OS-level sandbox.
For untrusted hostile code, use container/VM isolation in addition to this package.
Memory-limit caveat: RLIMIT_AS is platform-dependent. On macOS, address-space limits may not behave as strictly as Linux.
Common Gotchas
engineis required forrun_code(...); there is no implicit backend selection.policyandpolicy_fileare mutually exclusive; pass only one.- In
allowmode,allowed_globalscontrols both input key injection andextra_globals. importlibis intentionally blocked in all modes.- Package environments require pinned specs (
name==version).
More Information
- Full documentation and contributor workflow: README.md
- Security policy: SECURITY.md
- Issue tracker: GitHub Issues
Project details
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 safe_py_runner-0.1.7.tar.gz.
File metadata
- Download URL: safe_py_runner-0.1.7.tar.gz
- Upload date:
- Size: 58.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1153384884a3e1e4bf0e59f0ab4dcbd19639eebbda550949c33dab6304293887
|
|
| MD5 |
1004d8666338c371f98f5461b9b79e80
|
|
| BLAKE2b-256 |
128932df97bb5de1d0f973a0ef6ff7289d81dc44f57ce9c0157d297abdcd9e0f
|
Provenance
The following attestation bundles were made for safe_py_runner-0.1.7.tar.gz:
Publisher:
release.yml on adarsh9780/safe-py-runner
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
safe_py_runner-0.1.7.tar.gz -
Subject digest:
1153384884a3e1e4bf0e59f0ab4dcbd19639eebbda550949c33dab6304293887 - Sigstore transparency entry: 999664892
- Sigstore integration time:
-
Permalink:
adarsh9780/safe-py-runner@340c53431b640e14fd51259ecfbdfa26eee9b799 -
Branch / Tag:
refs/tags/v0.1.7 - Owner: https://github.com/adarsh9780
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@340c53431b640e14fd51259ecfbdfa26eee9b799 -
Trigger Event:
push
-
Statement type:
File details
Details for the file safe_py_runner-0.1.7-py3-none-any.whl.
File metadata
- Download URL: safe_py_runner-0.1.7-py3-none-any.whl
- Upload date:
- Size: 27.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9699089926aafe058bbcb6a76cdacdae8fdfc3961ab130f27a964aa4e3528b02
|
|
| MD5 |
9444535c093d979b798cddb1075a2174
|
|
| BLAKE2b-256 |
ec7834911e39f66620ee496f5d8d2167d9005babedd984466b47d6aebb1547f9
|
Provenance
The following attestation bundles were made for safe_py_runner-0.1.7-py3-none-any.whl:
Publisher:
release.yml on adarsh9780/safe-py-runner
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
safe_py_runner-0.1.7-py3-none-any.whl -
Subject digest:
9699089926aafe058bbcb6a76cdacdae8fdfc3961ab130f27a964aa4e3528b02 - Sigstore transparency entry: 999664982
- Sigstore integration time:
-
Permalink:
adarsh9780/safe-py-runner@340c53431b640e14fd51259ecfbdfa26eee9b799 -
Branch / Tag:
refs/tags/v0.1.7 - Owner: https://github.com/adarsh9780
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@340c53431b640e14fd51259ecfbdfa26eee9b799 -
Trigger Event:
push
-
Statement type: