epicbox2


Nameepicbox2 JSON
Version 2.0.0 PyPI version JSON
download
home_pageNone
SummaryEpicBox runs untrusted code in secure Docker based sandboxes
upload_time2024-04-24 23:32:16
maintainerNone
docs_urlNone
authorPavel Sviderski <ps@stepik.org>, Claudio Spiess
requires_python>=3.10
licenseMIT License Copyright (c) 2018 Pavel Sviderski Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
keywords docker sandbox
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI
coveralls test coverage No coveralls.
            # epicbox2

A Python library to run untrusted code in secure, isolated [Docker](https://www.docker.com/)
based sandboxes.

It allows to spawn a process inside one-time Docker container, send data
to stdin, and obtain its exit code and stdout/stderr output.  It's very similar
to what the [`subprocess`](https://docs.python.org/3/library/subprocess.html#module-subprocess)
module does but additionally you can specify a custom environment for the process
(a Docker [image](https://docs.docker.com/v17.09/engine/userguide/storagedriver/imagesandcontainers/))
and limit the CPU, memory, disk, and network usage for the running process.

## Usage
Run a simple Python script in a one-time Docker container using the
[`python:3.6.5-alpine`](https://hub.docker.com/_/python/) image:
```python
import epicbox

epicbox.configure(
    profiles=[
        epicbox.Profile('python', 'python:3.6.5-alpine')
    ]
)
files = [{'name': 'main.py', 'content': b'print(42)'}]
limits = {'cputime': 1, 'memory': 64}
result = epicbox.run('python', 'python3 main.py', files=files, limits=limits)

```
The `result` value is:
```python
{'exit_code': 0,
 'stdout': b'42\n',
 'stderr': b'',
 'duration': 0.143358,
 'timeout': False,
 'oom_killed': False}
```

Alternatively, you can also use the session context manager:
```python
from epicbox import create_session

with create_session("python") as session:
    command = (
        "python3 -c 'import sys; "
        'print("stdout data"); print("stderr data", file=sys.stderr)\''
    )
    result = session.exec(command)
    # result contains stdout and stderr
```

The advantage of a session is that a container will start upon entering the context manager, and commands can be run via `exec`. The standard `run` commands will create and start a _new_ container for every command.

### Available Limit Options

The available limit options and default values:

```
DEFAULT_LIMITS = {
    # CPU time in seconds, None for unlimited
    'cputime': 1,
    # Real time in seconds, None for unlimited
    'realtime': 5,
    # Memory in megabytes, None for unlimited
    'memory': 64,

    # limit the max processes the sandbox can have
    # -1 or None for unlimited(default)
    'processes': -1,
}
```

### Advanced usage
A more advanced usage example of `epicbox` is to compile a C++ program and then
run it multiple times on different input data.  In this example `epicbox` will
run containers on a dedicated [Docker Swarm](https://docs.docker.com/swarm/overview/)
cluster instead of locally installed Docker engine:
```python
import epicbox

PROFILES = {
    'gcc_compile': {
        'docker_image': 'stepik/epicbox-gcc:6.3.0',
        'user': 'root',
    },
    'gcc_run': {
        'docker_image': 'stepik/epicbox-gcc:6.3.0',
        # It's safer to run untrusted code as a non-root user (even in a container)
        'user': 'sandbox',
        'read_only': True,
        'network_disabled': False,
    },
}
epicbox.configure(profiles=PROFILES, docker_url='tcp://1.2.3.4:2375')

untrusted_code = b"""
// C++ program
#include <iostream>

int main() {
    int a, b;
    std::cin >> a >> b;
    std::cout << a + b << std::endl;
}
"""
# A working directory allows to preserve files created in a one-time container
# and access them from another one. Internally it is a temporary Docker volume.
with epicbox.working_directory() as workdir:
    epicbox.run('gcc_compile', 'g++ -pipe -O2 -static -o main main.cpp',
                files=[{'name': 'main.cpp', 'content': untrusted_code}],
                workdir=workdir)
    epicbox.run('gcc_run', './main', stdin='2 2',
                limits={'cputime': 1, 'memory': 64},
                workdir=workdir)
    # {'exit_code': 0, 'stdout': b'4\n', 'stderr': b'', 'duration': 0.095318, 'timeout': False, 'oom_killed': False}
    epicbox.run('gcc_run', './main', stdin='14 5',
                limits={'cputime': 1, 'memory': 64},
                workdir=workdir)
    # {'exit_code': 0, 'stdout': b'19\n', 'stderr': b'', 'duration': 0.10285, 'timeout': False, 'oom_killed': False}
```

## Installation
`epicbox` can be installed by running `pip install epicbox2`. It's tested on Python 3.4+ and
Docker 1.12+.

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "epicbox2",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.10",
    "maintainer_email": null,
    "keywords": "docker, sandbox",
    "author": "Pavel Sviderski <ps@stepik.org>, Claudio Spiess",
    "author_email": null,
    "download_url": "https://files.pythonhosted.org/packages/24/25/b059ec1464f20568bd614014f878ee8295c4b97ec73a0f7cce8b950c3da3/epicbox2-2.0.0.tar.gz",
    "platform": null,
    "description": "# epicbox2\n\nA Python library to run untrusted code in secure, isolated [Docker](https://www.docker.com/)\nbased sandboxes.\n\nIt allows to spawn a process inside one-time Docker container, send data\nto stdin, and obtain its exit code and stdout/stderr output.  It's very similar\nto what the [`subprocess`](https://docs.python.org/3/library/subprocess.html#module-subprocess)\nmodule does but additionally you can specify a custom environment for the process\n(a Docker [image](https://docs.docker.com/v17.09/engine/userguide/storagedriver/imagesandcontainers/))\nand limit the CPU, memory, disk, and network usage for the running process.\n\n## Usage\nRun a simple Python script in a one-time Docker container using the\n[`python:3.6.5-alpine`](https://hub.docker.com/_/python/) image:\n```python\nimport epicbox\n\nepicbox.configure(\n    profiles=[\n        epicbox.Profile('python', 'python:3.6.5-alpine')\n    ]\n)\nfiles = [{'name': 'main.py', 'content': b'print(42)'}]\nlimits = {'cputime': 1, 'memory': 64}\nresult = epicbox.run('python', 'python3 main.py', files=files, limits=limits)\n\n```\nThe `result` value is:\n```python\n{'exit_code': 0,\n 'stdout': b'42\\n',\n 'stderr': b'',\n 'duration': 0.143358,\n 'timeout': False,\n 'oom_killed': False}\n```\n\nAlternatively, you can also use the session context manager:\n```python\nfrom epicbox import create_session\n\nwith create_session(\"python\") as session:\n    command = (\n        \"python3 -c 'import sys; \"\n        'print(\"stdout data\"); print(\"stderr data\", file=sys.stderr)\\''\n    )\n    result = session.exec(command)\n    # result contains stdout and stderr\n```\n\nThe advantage of a session is that a container will start upon entering the context manager, and commands can be run via `exec`. The standard `run` commands will create and start a _new_ container for every command.\n\n### Available Limit Options\n\nThe available limit options and default values:\n\n```\nDEFAULT_LIMITS = {\n    # CPU time in seconds, None for unlimited\n    'cputime': 1,\n    # Real time in seconds, None for unlimited\n    'realtime': 5,\n    # Memory in megabytes, None for unlimited\n    'memory': 64,\n\n    # limit the max processes the sandbox can have\n    # -1 or None for unlimited(default)\n    'processes': -1,\n}\n```\n\n### Advanced usage\nA more advanced usage example of `epicbox` is to compile a C++ program and then\nrun it multiple times on different input data.  In this example `epicbox` will\nrun containers on a dedicated [Docker Swarm](https://docs.docker.com/swarm/overview/)\ncluster instead of locally installed Docker engine:\n```python\nimport epicbox\n\nPROFILES = {\n    'gcc_compile': {\n        'docker_image': 'stepik/epicbox-gcc:6.3.0',\n        'user': 'root',\n    },\n    'gcc_run': {\n        'docker_image': 'stepik/epicbox-gcc:6.3.0',\n        # It's safer to run untrusted code as a non-root user (even in a container)\n        'user': 'sandbox',\n        'read_only': True,\n        'network_disabled': False,\n    },\n}\nepicbox.configure(profiles=PROFILES, docker_url='tcp://1.2.3.4:2375')\n\nuntrusted_code = b\"\"\"\n// C++ program\n#include <iostream>\n\nint main() {\n    int a, b;\n    std::cin >> a >> b;\n    std::cout << a + b << std::endl;\n}\n\"\"\"\n# A working directory allows to preserve files created in a one-time container\n# and access them from another one. Internally it is a temporary Docker volume.\nwith epicbox.working_directory() as workdir:\n    epicbox.run('gcc_compile', 'g++ -pipe -O2 -static -o main main.cpp',\n                files=[{'name': 'main.cpp', 'content': untrusted_code}],\n                workdir=workdir)\n    epicbox.run('gcc_run', './main', stdin='2 2',\n                limits={'cputime': 1, 'memory': 64},\n                workdir=workdir)\n    # {'exit_code': 0, 'stdout': b'4\\n', 'stderr': b'', 'duration': 0.095318, 'timeout': False, 'oom_killed': False}\n    epicbox.run('gcc_run', './main', stdin='14 5',\n                limits={'cputime': 1, 'memory': 64},\n                workdir=workdir)\n    # {'exit_code': 0, 'stdout': b'19\\n', 'stderr': b'', 'duration': 0.10285, 'timeout': False, 'oom_killed': False}\n```\n\n## Installation\n`epicbox` can be installed by running `pip install epicbox2`. It's tested on Python 3.4+ and\nDocker 1.12+.\n",
    "bugtrack_url": null,
    "license": "MIT License  Copyright (c) 2018 Pavel Sviderski  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ",
    "summary": "EpicBox runs untrusted code in secure Docker based sandboxes",
    "version": "2.0.0",
    "project_urls": {
        "Homepage": "https://github.com/claudiosv/epicbox2"
    },
    "split_keywords": [
        "docker",
        " sandbox"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "d23bba988884238052642002d8a1041308ac01d9f4fb5df4ab010b48b69dbcf7",
                "md5": "da4cbb7657260570f3c92bb4c2035320",
                "sha256": "3a5e87f34e5bef830cf5872e7c85273be08802bd361fc4bb04d96d9a28a64ace"
            },
            "downloads": -1,
            "filename": "epicbox2-2.0.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "da4cbb7657260570f3c92bb4c2035320",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.10",
            "size": 17017,
            "upload_time": "2024-04-24T23:32:14",
            "upload_time_iso_8601": "2024-04-24T23:32:14.186771Z",
            "url": "https://files.pythonhosted.org/packages/d2/3b/ba988884238052642002d8a1041308ac01d9f4fb5df4ab010b48b69dbcf7/epicbox2-2.0.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "2425b059ec1464f20568bd614014f878ee8295c4b97ec73a0f7cce8b950c3da3",
                "md5": "b874ad457c8349182d07942554305f3f",
                "sha256": "1417a49b681db4e1ce0021bb4b3f84ad09160ee2f40526a7e31a9485b4058c9c"
            },
            "downloads": -1,
            "filename": "epicbox2-2.0.0.tar.gz",
            "has_sig": false,
            "md5_digest": "b874ad457c8349182d07942554305f3f",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.10",
            "size": 22147,
            "upload_time": "2024-04-24T23:32:16",
            "upload_time_iso_8601": "2024-04-24T23:32:16.129662Z",
            "url": "https://files.pythonhosted.org/packages/24/25/b059ec1464f20568bd614014f878ee8295c4b97ec73a0f7cce8b950c3da3/epicbox2-2.0.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-04-24 23:32:16",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "claudiosv",
    "github_project": "epicbox2",
    "travis_ci": true,
    "coveralls": false,
    "github_actions": false,
    "lcname": "epicbox2"
}
        
Elapsed time: 0.23520s