|
from flask import Flask, request, jsonify, send_from_directory |
|
from jupyter_client import KernelManager |
|
import sys, io, time, queue, os |
|
|
|
|
|
app = Flask(__name__, static_url_path='/static', static_folder='static') |
|
TIMEOUT = os.getenv("TIMEOUT", 60) |
|
|
|
km = KernelManager(kernel_name='python3') |
|
|
|
km.start_kernel() |
|
kc = km.client() |
|
|
|
|
|
@app.route("/", methods=["HEAD", "GET"]) |
|
def index(): |
|
return send_from_directory(directory="static", path="index.html") |
|
|
|
@app.route('/execute', methods=['POST']) |
|
def execute_code(): |
|
global kc |
|
code = request.json.get('code') |
|
if not code: |
|
return jsonify({'error': 'No code provided'}), 400 |
|
|
|
outputs = [] |
|
start_time = time.time() |
|
|
|
_ = kc.execute(code) |
|
|
|
success = True |
|
error = None |
|
|
|
while True: |
|
try: |
|
|
|
if time.time() - start_time > TIMEOUT: |
|
outputs.append({"text": f"Code execution has timed out (max {TIMEOUT}sec)."}) |
|
success = False |
|
error = "TimeOut" |
|
km.interrupt_kernel() |
|
break |
|
|
|
|
|
msg = kc.get_iopub_msg(timeout=1) |
|
|
|
|
|
if msg['header']['msg_type'] == 'status' and msg['content']['execution_state'] == 'idle': |
|
break |
|
|
|
|
|
if msg['header']['msg_type'] == 'stream': |
|
outputs.append({"text": msg['content']['text']}) |
|
|
|
|
|
elif msg['header']['msg_type'] == 'error': |
|
outputs.append({"text": "\n".join(msg['content']['traceback'])}) |
|
success = False |
|
error = msg["content"]["ename"] |
|
|
|
|
|
elif msg['header']['msg_type'] == 'display_data': |
|
msg["content"]["data"]["text"] = msg["content"]["data"].pop("text/plain") |
|
outputs.append(msg["content"]["data"]) |
|
|
|
|
|
except queue.Empty: |
|
print("No message received (timeout)", ) |
|
if not kc.is_alive(): |
|
outputs.append({"text": "Kernel has died!"}) |
|
success = False |
|
error = "KernelDied" |
|
km.restart_kernel() |
|
break |
|
|
|
return jsonify({ |
|
'result': outputs, |
|
'success': success, |
|
'error': error |
|
}) |
|
|
|
@app.route('/restart', methods=['POST']) |
|
def restart_kernel(): |
|
global kc |
|
km.restart_kernel() |
|
kc = km.client() |
|
return jsonify(status="Kernel has been restarted."), 200 |
|
|
|
@app.route('/health', methods=['GET']) |
|
def health_check(): |
|
return jsonify(status="healthy"), 200 |
|
|
|
if __name__ == '__main__': |
|
app.run(host='0.0.0.0', port=7860) |