Flask is a nifty module that has a peculiar origin :
“It came out of an April Fool’s joke but proved popular enough to make into a serious application in its own right.” Armin Ronacher - Creator of Flask
Despite it’s humble beginnings, Flask has grown into an extremely versatile web application framework, and is used for both tiny web server projects up to serious multi-developer projects used by a large userbase.
Web basics
The HyperText Transfer Protocol (HTTP) has a number of request methods. The oldest and most common is GET which is often used to simply retrieve data from the server.
The other common method is POST, used for e.g. “posting” data to the server.
Additional methods include PUT, DELETE, HEAD, PATCH and several more.
So why might we be interested in writing a web-application? In essence this comes down to “why might we be interested in a centralized user interface model”?
From my experience, the answer is that there are use-cases where developing and distributing traditional User Interfaces is not a good model.
For example, you might want to provide users access to data that you don’t want to have replicated each time a new user wants to access it.
Alternatively you might be actively developing the application used, and not want to continuously remind users to upgrade to the latest version of your software.
Even when you don’t have users, you might prefer to develop a server interface so that you don’t have to carry data around with you to conferences / when away from the office.
Whatever the reason web interfaces are growing in popularity, and the Python community has responded to that demand.
Other popular web frameworks for Python include Django, Pyramid, CherryPy, and Web2Py to name but a few.
The following iframes show embedded, real-time responses from a running Flask application server.
/
One of the most basic respones is a simple line of text showing that the server is working correctly.
<iframe height=100 src=”http://apollo.ex.ac.uk:8000/”></iframe>
/42
Passing information as a URL parameter is one of the simplest ways of transfering data to the server.
This response shows that the information is received on the server, and the generated response incorporates this data.
<iframe height=100 src=”http://apollo.ex.ac.uk:8000/42”></iframe>
/power
One of the most common ways of interacting with a server is via a form; this response displays a form; and subsequently generates a response from the GET parameters - parameters that get passed into the request url in a special format.
<iframe height=100 src=”http://apollo.ex.ac.uk:8000/power”></iframe>
/plot
In order to use web interfaces for science, we need to integrate scientific content; in this case a simple plot is generated dynamically each time the page is visited and rendered in the response.
<iframe width=400 height=400 src=”http://apollo.ex.ac.uk:8000/plot”></iframe>
/random
In addition to generating line plots of 1d data, we can generate 2d data and display it using images/heatmaps.
<iframe width=400 height=400 src=”http://apollo.ex.ac.uk:8000/random”></iframe>
/plotly
In-browser visualizations are becoming increasingly sophisticated and able to rival native desktop applications.
Plotly incorporates the powerful d3.js vector graphics library and stack.gl (on top of webGL) to bring a large range of scientific plots and visualizations to the browser.
<iframe height=400 width=800 src=”http://apollo.ex.ac.uk:8000/plotly”></iframe>
<iframe height=800 width=800 src=”http://apollo.ex.ac.uk:8000/plotly_with_get/3d”></iframe>
Getting Flask to display a “Hello, World” style message is really easy!
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello World!'
if __name__ == '__main__':
app.run()
A quick dissection:
Flask
class from the flask
module.app
app.route
decorator supplying the route urlif __name__ == "__main__":
-block to run the app.A route is a url that the application will render; the “root” url is rendered when no additional relative url path is given.
E.g. when we navigate to the Exeter university domain:
http://www.exeter.ac.uk/
we get the home page. This is at the root of the exeter.ac.uk
domain.
If we then click on the research link, we are directed to the relative
path /research/
(the full url is http://www.exeter.ac.uk/
), and are
displayed new content that pertains to research being done at the university.
Create a new script and copy and paste the code above.
Edit the root (aka home) rendering function to display the text
Hello!
Welcome to YOURNAME's site
(replace YOURNAME with your name)
Note that you can’t use newline characters (“\n”) as these don’t create line breaks in web-pages; instead use the html code for a line break :
<br>
Next, add another route at “/about” that renders a small information text explaining that this site is part of a python exercise.
As well as static routes, Flask makes it’s easy to add routes that accept variables, such as
/file/001
/project/12/user/133/
/search/larynx
ie one or more numerical fields, or string fields.
The syntax for adding a variable route like this is straight-forward
@app.route('/project/<int:project_id>')
def show_user_profile(project_id):
return 'You selected project %d' % project_id
If no converter is specified (int
above), the variable will be passed
in as a string. The converter can be one of int
, float
, path
, which will
convert the strint to integers, floating point numbers, or a path (i.e. string
which can include a forward-slash).
Create a flask app similar to the “Hello, world” sample, but add in a route that generates and serves a randomly generated sequence of number and smoothes those numbers using a gaussian filter (you will need to refer back to the Numpy and Scipy sections!).
Add in a variable to the route, to allow the user to specify the width (sigma) for the gaussian smoothing.
Also generate a plot of the data as well as the smoothed line, and serve the plot. There are two main ways to do this; either create a real file, and serve that, or generate an in memory file and convert the in-memory file to a base-64 encoded string; the base-64 encoded string can be embedded in the returned string and will show up as an image.
While not technically part of learning about Flask, one of the motivations for using Flask is to provide a user interface for our users.
As such, it’s worth pointing out, that many of the standard classical GUI elements have HTML equivalents;
The <input>
element provides input boxes for:
type=text
type=number
type=button
type=date
type=color
type=password
type=radio
type=range
In addition, there’s a select tag for defining a drop down list, progress for displaying a progress bar, and libraries such as JQuery-UI or Bootstrap define many more user interface elements.
In terms of graphical elements, in addition to the img tag for static images and the video tag to stream videos, there also a drawable canvas tag for general 2d graphics, which now also supports 3D graphics support via the WebGL specification.
The internet (meaning the HTML protocol in this case) is often referred to as stateless. This means the the state of information is not automatically retained between refreshes of a site (or navigation between child pages).
Instead, website developers have to use either client-side or server-side methods to store information between these operations.
Most heavy-duty state storage is done via server databases, but small pieces of information are often stored on the client (i.e. by your browser); the main place such information is stored is in cookies.
To start storing information between page calls in Flask, we’re going to use the session storage object, which can be accessed as if it were a dictionary (i.e. using keys to access values.
As an example, if we modify the home route of the initial example as follows
from flask import Flask, session
app = Flask(__name__)
app.secret_key = 'SUPERSECRETKEY'
@app.route('/')
def hello_world():
if "visits" not in session:
session["visits"] = 1
else:
session["visits"] += 1
return 'Hello World! (%d times)'%num
if __name__ == '__main__':
app.run()
We will see
Hello World! (1 times)
when we first visit the site.
However, if we press refresh, we will get
Hello World! (2 times)
, 3 times on the next and so on.
While generating data and responding to input using a “traditional” server model works and is how many websites still operate, most modern websites now incorporate a reactive element.
This means that instead of a classic request-response cycle (updated to include the AJAX model of not refreshing a whole page), many sites now use websockets, which provide bi-directional messaging between client and server to allow for real-time update of browser content.
Flask extensions exist to work with websockets, allowing developers to create truly reactive experiences.
Tornado (Python) and NodeJS (which allows for a pure Javascript developement environment instead of switching between a server-side language like Python or Ruby, and client-side Javascript) both offer websockets as default.
Lastly, meteor, which is built “on top” of NodeJS, is a single source web application framework which aims to provide an environment for seamlessly writing web applications where the distinction between and server and client is virtually removed.
Initially websites were mainly displays of static information, and any interactivity was afforded by sending information back to the server (via a form), and having a new, but equally static page returned (containing mainly static HTML elements and text).
However as well as rendering these HTML elements, the front-end of modern web-applications are “brought to life” by Javascript, which provides the majority of the dynamical aspects to web apps.
Initially this was done through pure Javascript, followed by the massively popular JQuery library which provided quick and convenient methods for dynamical (client-side) webpage manipulations.
More recently, impressive client-side frameworks have emerged, such as Google’s AngularJS, Backbone.js, Ember.js, and React by Facebook and Instagram. These add either a full Model-View-Controller (MVC) framework to the front-end of a website, or parts of it.
The MVC architectural pattern for implementing user interfaces centres around dividing “… a given software application into three interconnected parts, so as to separate internal representations of information from the ways that information is presented to or accepted from the user”.
In short, instead of the client receiving mostly static pages, nowadays most larger websites offer full client-side web applications that are essentially programs running inside browsers, which still synchronize data back and fore with the server.
There are several Flask extensions that make working with such frameworks straightforward, such as Flask-Resful for creating a RESTful web app “endpoint”, as well as template projects showing how to combine Flask with e.g. Angular.
If you would like to know more about getting started with writing a full web application, drop me an email and I’ll give you some tips on how to get started!