Flask is an amazingly useful microframework that can help you to create web applications. More than that, it lets you do it with Python, which can be very handy for taking a program built in Python, and turning it into a web application. In addition to python, Flask also requires a webpage built in HTML and CSS to serve as the user-interface, and this part can be a little foreign to those used to working on the back-end of things. Flask is able to use embedded Python instead of JavaScript by using a language called Brython, which is basically python for browsers. We’re not going to talk about design fundamentals or anything, but we will discuss how the Brython makes reference to the HTML. To start with, let’s look at our file structure. For this example, we’re going to have 3 files, “index.html”, “app.py”, and “program.py”. What are these files? “index.html” is the webpage, which contains the embedded Brython. “app.py” is the interface between your program and the application, and while it might normally be named after your application, I’m calling it “app.py” so you know what it contains. “program.py” contains your program that you will probably have developed independently of Flask, and may actually be several files, but for this example I’m assuming everything is contained in one file. Let’s look at each file, or at least the relevant parts. “index.html” contains some HTML and some embedded Brython:
<body onload="brython(1)">
<script type="text/python3">
from browser import document, ajax, window
import json
import warnings
def show_results(response):
"""1"""
if response.status==200 or response.status==0:
data = json.loads(response.response)
document["title"].html = data['sum']
else:
warnings.warn(response.text)
def do_math(ev):
"""2 - Add one to input."""
req = ajax.ajax()
req.bind('complete', show_results)
req.open('POST', '/compute', True)
req.set_header('content-type','application/json')
data = json.dumps({'input': document['input'].value})
req.send(data)
"""3"""
document["add_button"].bind("click", do_math)
</script>
<!-- 4 -->
<input type=“text” id=“input”></input></div>
<button id=“add_button" type="button">Add One!</button>
<div id=“output”></div>
</body>
This might look a little confusing at first, but let’s see if we can. Boil it down a little. This very simple application takes as input a number, adds one, and displays the sum on the page. I have numbered the sections for reference, using appropriate commenting styles. We’ll start with section 4, which is down in the HTML. Notice that there is a textbox for input, a button, and a generic div to hold our eventual output. The main thing you need to worry about here is the id
parameter for each tag, which labels it. Now let’s look at section 3. This is the code that uses the imported document
to reference a specific tag, in this case our button called add_button
, and uses .bind
to bind an action on the button, click
, to a function defined above, do_math
. Now that we’ve bound the action to a function, let’s discuss the function. Section 2, do_math, is the function that will connect to our program outside of this page. First, it creates an Ajax request, and then similar to how we bound the button, it binds the action complete
to the function show_results
, so that when the request is complete it will run that function. Then it uses .open
to set GET
or POST
, and what action is to be taken upon making the request, here we are calling /compute
. It sets the header to establish the format it will send data in, and then we get the data to be sent. Again, we are using the document
to reference a tag, this time the input
tag so we can grab the input value. Finally we send the data, and the next stage begins. For the next part we’ll look at a function in “app.py”:
Import program
@app.route(‘/compute’, methods=[‘GET’, ‘POST’])
def compute_sum():
data = request.json
sum = program.add_one(data[‘input’])
return jsonify({‘sum’ : sum})
There is a little more to this file, but for now I’m only showing the relevant bits. Notice that the function is called compute_sum
, but we just set our request to access /compute
! Don’t worry, there’s a reason for this. Above that line, app.route
includes the parameter /compute
, and this is where it sets the name that the Brython code and the Ajax request will be able to use to identify it. Otherwise this function is fairly straight forward. We get the data from the request, and because we set the content to be JSON, we can access it like JSON, kind of like a dictionary. After running our function from the program, we return the output by turning it back into JSON. In this way we could actually send multiple outputs at the same time, but for now we just need to send one. Now that the program has been run and we’re returning the output, let’s head back to the HTML file. Back in section 1 you’ll see it starts with an if
statement. This is because it this point we don’t know if everything worked or not, so we need to check that status of our request before we start trying to use the data. There are numerous error codes you could potentially receive, depending on the problem, so we’re focussing on a success, which is the code 200. If we get that, everything is fine, otherwise we print it to find out what went wrong. Assuming we have a successful response, we’re simply accessing the data and printing it by setting the contents of the div tag we made earlier to the output. Congrats, we have now traced the flow of data from the collection of user input, all the way to the display of final output. Of course this may get more complex depending of the complexity of your program, and the kind of input your need to collect or the kind of output you need to display. But hopefully understanding the basic flow of the data will help you to figure out how set up your Flask application.
Top comments (1)
Awesome! Thanks for this great piece. Any additional Flask-Brython application examples/snippets (or links to the same) would be greatly appreciated :-) One small step for a dev, one giant leap for letting Python rule the web :o))