chmielvu commited on
Commit
1712ab6
·
verified ·
1 Parent(s): 05668aa

Upload folder using huggingface_hub

Browse files
Files changed (4) hide show
  1. Dockerfile +14 -0
  2. README.md +11 -6
  3. python_executor.py +74 -0
  4. requirements.txt +4 -0
Dockerfile ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.12-slim
2
+
3
+ RUN useradd -m -u 1000 user
4
+ WORKDIR /app
5
+
6
+ COPY --chown=user requirements.txt /app/requirements.txt
7
+ RUN pip install --no-cache-dir -U pip && pip install --no-cache-dir -r /app/requirements.txt
8
+
9
+ COPY --chown=user . /app
10
+
11
+ USER user
12
+ ENV HOME=/home/user PATH=/home/user/.local/bin:$PATH
13
+
14
+ CMD ["waitress-serve", "--host=0.0.0.0", "--port=7860", "python_executor:app"]
README.md CHANGED
@@ -1,10 +1,15 @@
1
  ---
2
- title: Kgot Python Executor
3
- emoji: 📚
4
- colorFrom: red
5
- colorTo: green
6
  sdk: docker
7
- pinned: false
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
1
  ---
2
+ title: KGoT Python Executor
3
+ emoji: 🐍
4
+ colorFrom: blue
5
+ colorTo: gray
6
  sdk: docker
7
+ app_port: 7860
8
  ---
9
 
10
+ Remote Python executor for Knowledge Graph of Thoughts.
11
+
12
+ Exposes:
13
+ - `GET /` basic service info
14
+ - `GET /health` health check
15
+ - `POST /run` code execution endpoint compatible with the KGoT Python tool
python_executor.py ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import re
2
+ import subprocess
3
+ import sys
4
+ from concurrent.futures import ThreadPoolExecutor, TimeoutError
5
+
6
+ import requests
7
+ from flask import Flask, jsonify, request
8
+ from langchain_experimental.utilities import PythonREPL
9
+
10
+ app = Flask(__name__)
11
+ PYTHON_EXECUTOR_HOST = "0.0.0.0"
12
+ PYTHON_EXECUTOR_PORT = 7860
13
+
14
+
15
+ def is_standard_lib(package: str) -> bool:
16
+ return package in sys.stdlib_module_names
17
+
18
+
19
+ def install(package: str) -> None:
20
+ subprocess.check_call([sys.executable, "-m", "pip", "install", package])
21
+
22
+
23
+ @app.get("/")
24
+ def root():
25
+ return {"service": "kgot-python-executor", "port": PYTHON_EXECUTOR_PORT}
26
+
27
+
28
+ @app.get("/health")
29
+ def health():
30
+ return {"status": "ok"}
31
+
32
+
33
+ @app.route('/run', methods=['POST'])
34
+ def run_code() -> tuple[requests.Response, int]:
35
+ timeout_seconds = 240
36
+
37
+ required_modules = request.json.get('required_modules', [])
38
+ if required_modules:
39
+ for module in required_modules:
40
+ if not is_standard_lib(module):
41
+ install(module)
42
+
43
+ code = request.json.get('code')
44
+ if not code:
45
+ return jsonify({"error": "No code provided"}), 400
46
+
47
+ python_repl = PythonREPL()
48
+
49
+ def execute_code() -> tuple[requests.Response, int]:
50
+ def is_error_string(s: str) -> bool:
51
+ error_pattern = re.compile(r'^[a-zA-Z_]+Error\((.*)\)$')
52
+ return bool(error_pattern.match(s))
53
+
54
+ result = python_repl.run(code)
55
+ if is_error_string(result):
56
+ return {"error": result}, 400
57
+ return {"output": result}, 200
58
+
59
+ executor = ThreadPoolExecutor(max_workers=1)
60
+ future = executor.submit(execute_code)
61
+
62
+ try:
63
+ result, status_code = future.result(timeout=timeout_seconds)
64
+ except TimeoutError:
65
+ return jsonify({"error": "Code execution timed out"}), 408
66
+ except Exception as e:
67
+ return jsonify({"error": str(e)}), 400
68
+
69
+ return jsonify(result), status_code
70
+
71
+
72
+ if __name__ == '__main__':
73
+ from waitress import serve
74
+ serve(app, host=PYTHON_EXECUTOR_HOST, port=PYTHON_EXECUTOR_PORT)
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ flask
2
+ waitress
3
+ requests
4
+ langchain_experimental