Skip to main content

Code Cantation

A safe, embeddable code executor for Python—usable both as a library and via a CLI.


Features

  • Script execution: Run arbitrary Python scripts with stdout capture.
  • Function execution: Define functions in code snippets and invoke them (with or without parameters).
  • Safety checks: Static AST-based analysis blocks imports of unsafe modules (e.g. os, subprocess) and calls to dangerous functions (eval, exec, etc.).
  • Error reporting: Any runtime errors are captured and returned in the output object.
  • Process isolation: Code runs in a separate process with configurable timeout and resource limits.
  • Dual usage: Importable as a Python package, or installed as a cantation CLI tool. Server mode is optional.
  • Command execution: Run direct commands (library/CLI only, no shell) with allowed-root safeguards.

Installation

Install from PyPI (library + CLI):

pip install code-cantation

To include FastAPI/uvicorn for server mode (optional extra):

pip install code-cantation[server]

Or install from source in editable mode:

git clone https://github.com/your-repo/code-cantation.git
cd code-cantation
pip install -e .

Usage as a Library

Import and invoke the Executor directly in your code:

from code_cantation import Executor

exe = Executor()

# 1. Run a simple script:
script = """
a = 10
b = 20
print('sum =', a + b)
"""  # note: no `return` in script mode
result = exe.execute(code=script)
print("Console:", result.console_log)

# 2. Call a function without parameters:
func_no_args = """
def greet():
    print('hello')
    return 'hello'
"""
res2 = exe.execute(code=func_no_args, code_type="FUNCTION")
print("Return:", res2.captured_output)

# 3. Call a function with parameters:
func_with_args = """
def add(a, b):
    print('adding', a, b)
    return a + b
"""
res3 = exe.execute(
    code=func_with_args,
    code_type="FUNCTION",
    input_values=[5, 7]
)
print("Return:", res3.captured_output)

# 4. Restrict file access to a specific folder:
restricted = exe.execute(
    code="open('data.txt', 'w').write('ok')",
    allowed_root="/sandbox/work"  # work_dir defaults to allowed_root
)
print("Error:", restricted.exec_error)

# 5. Check safety violation:
unsafe = "import requests"
res4 = exe.execute(code=unsafe)
print("Safety error:", res4.safety_violation)

# 6. Run a bash command (requires allowed_root):
bash_result = exe.execute_bash(
    command="pwd",
    allowed_root="/sandbox/work"
)
print("Bash output:", bash_result.console_log)

The execute(...) method returns a CodeExecutorOutput object with the following attributes:

  • console_log (str): Captured stdout from the snippet.
  • captured_output (any): Return value of a FUNCTION snippet (or None for scripts).
  • exec_error (str): Runtime error message if execution failed.
  • safety_violation (str): Description if safety checks failed.

By default, execution runs in a separate process with a 5s timeout, 5s CPU limit, and a 256MB memory limit. These can be overridden per call. If allowed_root is set, file access is restricted to that directory (read/write). Standard library and site-packages imports are still allowed (read-only), but local imports from outside allowed_root will be blocked.


Usage via CLI

Once installed, the cantation command is available on your PATH. All options mirror the library’s Executor.execute() parameters and always emit a JSON representation of the CodeExecutorOutput.

cantation [--code CODE  | --file FILE]
          [--bash CMD]
          [--no-safety]
          [--code-type {SCRIPT,FUNCTION}]
          [--input JSON_LIST]
          [--unsafe-modules MODULE [MODULE ...]]
          [--unsafe-functions FUNC [FUNC ...]]
          [--override-default-safety]
          [--timeout-sec SECONDS]
          [--cpu-time-limit-sec SECONDS]
          [--memory-limit-mb MB]
          [--allowed-root DIR]
          [--work-dir DIR]

Common Examples

  1. Run an inline script

    cantation \
      --code "print('Hello from CLI'); x = 1 + 2; print('x =', x)"
    

    Output

    {
      "console_log": "Hello from CLI x = 3",
      "captured_output": null,
      "exec_error": null,
      "safety_violation": null
    }
    
  2. Execute a Python file

    cantation --file path/to/script.py
    
  3. Invoke a no-arg function

    cantation \
      --code "def greet():
     print('Hi there'); return 'Hi'" \
      --code-type FUNCTION
    

    Output

    {
      "console_log": "Hi there",
      "captured_output": "Hi",
      "exec_error": null,
      "safety_violation": null
    }
    
  4. Invoke a function with parameters

    cantation \
      --code "def add(a, b):
     return a + b" \
      --code-type FUNCTION \
      --input '[5, 7]'
    

    Output

    {
      "console_log": "",
      "captured_output": 12,
      "exec_error": null,
      "safety_violation": null
    }
    
  5. Disable safety checks

    cantation --file my_script.py --no-safety
    
  6. Override unsafe modules/functions

    # Disallow use of 'os' and 'eval'
    cantation --file my_script.py \
      --unsafe-modules os \
      --unsafe-functions eval
    
  7. Install Libraries Required For Code Execution

    cantation \
     --install pyfiglet \
    --code "import pyfiglet; print(pyfiglet.figlet_format('Hello'))"
    
  8. Set resource limits

    cantation \
      --code "print('hello')" \
      --timeout-sec 3 \
      --cpu-time-limit-sec 2 \
      --memory-limit-mb 128
    

    Set any of these to 0 to disable that limit.

  9. Restrict file access

    cantation \
      --code "open('data.txt','w').write('ok')" \
      --allowed-root /sandbox/work
    
  10. Run a direct command (no shell)

cantation \
  --bash "python -c \"print('ok')\"" \
  --allowed-root /sandbox/work

Command execution is CLI/library only (not supported in server mode). Variable/command substitution (e.g., $HOME, $(...), backticks) is blocked. Shell operators (e.g., &&, |, redirection) are not supported.

Allowed:

  • Simple commands that operate inside allowed_root (e.g., python -c "print('ok')", ls ., cat file.txt)
  • Read-only access to allowed_root contents

Blocked:

  • Destructive commands like rm, rmdir, mv, chmod, chown, dd, mkfs*
  • Delete flags like --delete / -delete
  • Paths that resolve outside allowed_root

Usage As Server

Code Cantation can be run as a server/rest api. The server execute one code at time and therefore has an internal queue for requests.

Server mode requires the optional FastAPI/uvicorn extras:

pip install code-cantation[server]

If you only installed the core package, cantation --server will fail with a message telling you to install the server extras.

Start server (basic)

cantation --server --install pyfiglet fastapi uvicorn \
          --host 127.0.0.1 --port 9000

If you already installed the server extra, you can omit --install fastapi uvicorn.

Start server with allowed root (client-enforced)

The server reads allowed_root and work_dir from each request. Use these in your API payloads to restrict file access to a specific directory.

Start server securely (no Docker)

Run as a dedicated user with a restricted working directory:

sudo useradd -m cantation
sudo mkdir -p /srv/cantation/work
sudo chown -R cantation:cantation /srv/cantation
sudo -u cantation cantation --server --host 127.0.0.1 --port 9000

Optionally apply OS limits in the same shell:

ulimit -t 5 -v 1048576 -n 128 -u 64
sudo -u cantation cantation --server --host 127.0.0.1 --port 9000

Start server with Docker hardening (recommended)

docker run --rm -it \
  --read-only \
  --cap-drop=ALL \
  --security-opt no-new-privileges \
  --user 1000:1000 \
  --pids-limit 256 \
  --memory 1g \
  --cpus 2 \
  --tmpfs /tmp:rw,noexec,nosuid,size=64m \
  -p 9000:9000 \
  -v /host/allowed:/sandbox/work:rw \
  your-image \
  cantation --server --host 0.0.0.0 --port 9000

Call The API

curl -X POST http://127.0.0.1:9000/execute \
     -H "Content-Type: application/json" \
     -d '{
           "code": "import pyfiglet; print(pyfiglet.figlet_format(\"API\"))",
           "timeout_sec": 3,
           "cpu_time_limit_sec": 2,
           "memory_limit_mb": 128,
           "allowed_root": "/sandbox/work",
           "work_dir": "/sandbox/work"
         }'

Use 0 to disable a limit per request.

Recommended: always set allowed_root (and optionally work_dir) in requests to restrict file access to a specific directory. Combine this with container-level restrictions for stronger isolation.


Docker Run Recipes

These examples assume your app is installed inside the container and that you want to restrict file access to a single host directory mounted at /sandbox/work.

Library / CLI (interactive)

docker run --rm -it \
  --read-only \
  --cap-drop=ALL \
  --security-opt no-new-privileges \
  --user 1000:1000 \
  --pids-limit 128 \
  --memory 512m \
  --cpus 1 \
  --tmpfs /tmp:rw,noexec,nosuid,size=64m \
  -v /host/allowed:/sandbox/work:rw \
  your-image \
  cantation \
    --code "open('data.txt','w').write('ok')" \
    --allowed-root /sandbox/work

FastAPI Server

docker run --rm -it \
  --read-only \
  --cap-drop=ALL \
  --security-opt no-new-privileges \
  --user 1000:1000 \
  --pids-limit 256 \
  --memory 1g \
  --cpus 2 \
  --tmpfs /tmp:rw,noexec,nosuid,size=64m \
  -p 9000:9000 \
  -v /host/allowed:/sandbox/work:rw \
  your-image \
  cantation --server --host 0.0.0.0 --port 9000

Note: ensure your image includes the server extra (pip install code-cantation[server]).

Recommended: set allowed_root to /sandbox/work in your requests so file access is restricted to the mounted directory.

How It Works

If you don't provide the code type, the library will try to figure it out itself.

Executor Code Flow Logic

Internal Code Flow

Testing

A test script (test/test.py) is provided to exercise:

  1. Script execution
  2. Function execution (no args)
  3. Function execution (with args)
  4. Safety-check failures
  5. CLI behaviors

Run:

python test/test.py

Contributing

  1. Fork the repo and create your branch: git checkout -b feature/YourFeature
  2. Make your changes & add tests
  3. Run tests: python sample_test.py
  4. Submit a pull request

Metadata

Release files for code-cantation 0.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for code-cantation 0.1.2
File Size Uploaded Provenance
code_cantation-0.1.2.tar.gz 19.9 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for code-cantation 0.1.2
File Interpreter ABI Platform
code_cantation-0.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 35.9 kB

Release files / code_cantation-0.1.2.tar.gz

Download URL code_cantation-0.1.2.tar.gz
Size 19.9 kB
Tags Source
SHA-256 checksum
How to use checksums
fde48f0f2f369c2d0420920cd2e0ad882d4907206cf5869f1492fd875f12e155
BLAKE2b-256 checksum
How to use checksums
fa9f01e085b2e70a2c99dc68b40971c5327b6970ba9ab905f802831623de4be6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.10.0

Release files / code_cantation-0.1.2-py3-none-any.whl

Download URL code_cantation-0.1.2-py3-none-any.whl
Size 16.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
98d755d52cd81912de2e82f60e0c27120aec29f3b993ea6c676c0121290971ca
BLAKE2b-256 checksum
How to use checksums
964393794f3c456d661d774799f99698ad4b41c7d530639234dc972ddbf3c95f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.10.0

Security for code-cantation 0.1.2

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page