36
loading...
This website collects cookies to deliver better user experience
src/App.js
:let [notebook, updateNotebook] = useImmer([
{ input: "def fib(n):\n if n < 2:\n return 1\n return fib(n-1) + fib(n-2)", output: "" },
{ input: "print([fib(n) for n in range(1,11)])", output: "" },
{ input: "print(3**100)')", output: "" },
])
package.json
, as flask
default is different to sinatra
default:"proxy": "http://localhost:5000"
POST /code
endpoint.#!/usr/bin/env python3
from flask import Flask, request
from io import StringIO
import sys
class Capturing(list):
def __enter__(self):
self._stdout = sys.stdout
self._stderr = sys.stderr
self._stringio = StringIO()
sys.stdout = self._stringio
sys.stderr = self._stringio
return self
def __exit__(self, *args):
output = self._stringio.getvalue()
self.append(output)
sys.stdout = self._stdout
sys.stderr = self._stderr
app = Flask(__name__)
sessions = {}
@app.route("/code", methods=["POST"])
def code():
body = request.json
session_id = body["session_id"]
code = body["code"]
sessions.setdefault(session_id, {})
error = None
with Capturing() as output:
try:
exec(code, sessions[session_id])
except Exception as e:
error = str(e)
return {"output": output[0], "error": error}
Capturing
uses StringIO
to capture the output. As Python strings are not modifiable, and with
cannot be used to pass any interesting object, we need to wrap the return value in a one element list. That's why we have to extract it with output[0]
, not just output
. It would be cleaner with blocks but it's good enough.exec
is a bit problematic. In principle it takes three arguments - the code to be executed, globals dictionary, and locals dictionary. Unfortunately if you use it this way, you cannot execute recursive functions. Python would set fib
in locals dictionary, then when it tries to recurse, it would only look inside the globals dictionary. The only workaround is to pass same dictionary as both globals and locals, which conveniently is what already happens if we skip the last argument.$ pip3 install flask
$ npm install
$ flask run
$ npm run start
$ npx electron .