python-executor is a lightweight Flask server that executes user-written python functions within a jailed container.
# using python requests
requests.post('http://127.0.0.1:8080/execute', json={"script": "def main():\n\tprint('hello')\n\treturn {'data': 3}\n"})
# or curl
curl -X POST http://127.0.0.1:8080/execute \
-H "Content-Type: application/json" \
-d '{"script": "def main():\n\tprint(\"hello\")\n\treturn {\"data\": 3}"}'
{'result': {'data': 3}, 'stdout': 'hello'}
r = requests.post('http://127.0.0.1:8080/execute', json={"script": "def main():\n\tprint('hello')\n\timport subprocess\n\tsubprocess.run('touch test')\n\treturn {'data': 3}\n"})
{'error': 'Script failed or timed out'}
# Flask Logs
e94ad166_9cc9_42cf_8d9c_6b7f69bb7d7e_20250924.py
{'Type Banned': [<class 'ast.Import'>], 'Name Banned': ['subprocess']}
- Base server and sub-module implementation: 1.5 hrs
- Docker setup: .5 hrs
- nsjail setup: .5 hrs
Total Elapsed Time: ~2.5 hrs
Note: I didn't have time to set up GCP
If you want to standup the executor.Executor interface locally, create a python virtual environment loaded with requirements.txt and then run any of the test files (e.g. python3 -i tests/simple_sum.py and inspect result variable)
The python-executor image builds on top of the nsjailcontainer image found in the nsjail repo.
Make sure you have nsjailcontainer available (or a suitable alternative) prior to building the image
My local image size is ~336MB
docker build -t python-executor .
docker run -it -p 8080:8080 python-executor