-1

The attached Flask+Brython source code was supposed to print 20 random numbers (between -100 and 100) on the browser screen.

However, it doesn't.

The Brython script is failing to parse JSON data.

How can I fix this?

enter image description here

app.py

from flask import Flask, render_template
from flask import request, redirect
from flask_socketio import SocketIO, emit

async_mode = None
app = Flask(__name__)
socketio_obj = SocketIO(app)


@app.route('/', methods=['GET', 'POST'])
def index():
    import random
    import json
    random_list = []
    for i in range(0, 20):
        n = random.randint(-100, 100)
    random_list.append(n)
    json_data = str(json.dumps(random_list))
    return render_template('index.html', json_data=json_data)


if __name__ == '__main__':
    socketio_obj.run(app, debug=True)

index.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Brython Test</title>
    <script src="../static/brython/Brython-3.11.1/brython.js"></script>
    <script src="../static/brython/Brython-3.11.1/brython_stdlib.js"></script>
</head>
<body onload="brython()">
    <script type="text/python" src="../static/brython/index.py"></script>
</body>
</html>

index.py

from browser import document, window, console
import os   

random_list = "{{json_data}}"
document <= random_list
user366312
  • 16,949
  • 65
  • 235
  • 452

1 Answers1

1

Unfortunately you can only use the jinja syntax within a template and not in a loaded file. So you have nothing else to do than integrate the brython code into your template or obtain the data from another endpoint via ajax.

To pass a variable to brython, you can use the jinja filter tojson due to the similarity in syntax. This gives you the list of numbers and you can attach them to the document.

Flask (./app.py)
@app.route('/')
def index():
    random_list = [random.randint(-100, 100) for _ in range(20)]
    return render_template('index.html', **locals())
Brython (./index.html)
from browser import document

random_list = {{ random_list | tojson }}
document <= ','.join(str(item) for item in random_list)

If you want to get the data via Ajax, the following variant is possible.

Flask (./app.py)
from flask import jsonify
import random 

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/data')
def data():
    random_list = [random.randint(-100, 100) for _ in range(20)]
    return jsonify(random_list)
Brython (./static/brython/index.py)
from browser import ajax, document

read = lambda req: document <= ','.join(str(n) for n in req.json)
ajax.get("/data", mode="json", oncomplete=read)
Detlef
  • 6,137
  • 2
  • 6
  • 24
  • What does `**locals()` mean? – user366312 Feb 23 '23 at 21:37
  • So, that means I cannot keep Brython source code in a separate file?? – user366312 Feb 23 '23 at 21:42
  • `locals()` contains a dictionary of all local variables. By using `**locals()` the dict, consisting of identifier as key and assigned value, is expanded and transferred to the template. The variables are then available with their identifier in the template. It is an abbreviated notation of `render_template('index.html`, random_list=random_list)` – Detlef Feb 23 '23 at 21:43
  • You can keep the file separate if you're getting the data from a separate endpoint via ajax. – Detlef Feb 23 '23 at 21:44
  • *You can keep the file separate if you're getting the data from a separate endpoint via ajax.* --- Could you be kind enough to supply me with an example?? – user366312 Feb 23 '23 at 21:53
  • I added an example. You can find the documentation [here](https://brython.info/static_doc/en/browser.ajax.html). – Detlef Feb 23 '23 at 21:54