is52027c lab 12
flask & jinja
virtual server checklist
- check you can log in to your vs
- check you have git
- check you have an editor (vim, nano, emacs...)
- remember, we are using python 3; so either your commands use python3 or you have set up an alias as recommended in lab 5 http://gitlab.doc.gold.ac.uk/data-networks-web/lab-exercises/wikis/web-server
update your system:
sudo apt-get update
sudo apt-get upgrade
for more on the virtual servers see:
- http://gitlab.doc.gold.ac.uk/data-networks-web/lab-exercises/wikis/web-server
- https://www.doc.gold.ac.uk/dept/VirtualServer
pip
is pip installed?
pip list
if not
sudo apt-get update
sudo apt-get install python-pip
pip defaults to installing Python packages to a system directory (such as /usr/local/lib/python3.4). This requires root access. --user makes pip install packages in your home directory instead, which doesn't require any special privileges.
set up a git repo
create a git repo called term-2-lab
install flask
- pip install --user flask
note: pip defaults to installing Python packages to a system directory (such as /usr/local/lib/python3.4). This requires root access. --user makes pip install packages in your home directory instead, which doesn't require any special privileges.
- to list installed packages: pip list
hello, world
-
create a hello world app.
-
type it in by hand.
-
read the explanation of the different lines flask quickstart
run using development server
add
if __name__ == '__main__':
app.run(debug=True,host='0.0.0.0',port=8000)
port + ip
port 8000 is the port on which the virtual servers are available externally
host=0.0.0.0 makes the server externally visible
run your app
python3 hello_world.py
visit http://doc.gold.ac.uk/usr/
debug mode
debug = True
http://flask.pocoo.org/docs/0.12/quickstart/#debug-mode
This does the following things:
- it activates the debugger
- it activates the automatic reloader
- it enables the debug mode on the Flask application.
routing
- add a route that prints the time right now.
- you'll need to import the datetime module
- the date & time right now is given by datetime.datetime.now()
- but flask can only return a string so you also need str
- if you keep refreshing this view the time should keep updating
- => you can see that flask views are dynamic
variable rules
- add a route with a variable so that /hello/bob will return "hello, bob!"
- see variable rules
rss feeds
- to make things a bit more interesting, we'll write an app that shows news headlines from rss feeds.
- we'll use this again later when we look at templates
- we'll need the feedparser module
so pip install --user feedparser
here's the code
from flask import Flask
import feedparser
from random import randint
app = Flask(__name__)
BBC_FEED = "http://feeds.bbci.co.uk/news/rss.xml"
@app.route("/")
def headline():
feed = feedparser.parse(BBC_FEED)
article = feed['entries'][0]
return """<html>
<body>
<h1> BBC headline </h1>
<b>{0}</b> <br/>
<i>{1}</i> <br/>
<p>{2}</p> <br/>
</body>
</html>""".format(article.get("title"),
article.get("published"), article.get("summary"))
if __name__ == '__main__':
app.run(debug=True,host='0.0.0.0',port=8000)
- adapt the code to select a random headline from the first 10 in the rss feed
- you'll need the randint function from the random module
module names
remember your simple app that showed the time.
what happens if you rename your app datetime.py then try to run it?
see also: the python standard library https://docs.python.org/3/library/index.html
jinja templates
templates
-
we know we can return html from our flask view
-
but it would be better to follow 'separation of concerns' by using a templating system.
-
flask uses jinja
-
there's a quick intro on the flask site
-
jinja is a general templating system for python not just for flask
-
there's fuller documentation at Template Designer Documentation
-
it is used by Instagram, amongst others
render_template
-
to render a template you can use the render_template() method.
-
flask will look for templates in the templates folder
-
see http://flask.pocoo.org/docs/0.12/quickstart/#rendering-templates
try it
-
try creating a template for one of your mini-apps
-
pass it a variable, which is rendered in the template as {{ variable }}
for example
@app.route('/hello/<name>')
def hello(name=None):
return render_template('hello.html', name=name)
autoescaping
using jinja with flask helps tackle XSS because autoescaping is enabled for all templates ending in .html, .htm, .xml as well as .xhtml when using render_template()
other variables
other variables which are available in jinja include
-
config: The current configuration object (flask.config)
-
request: The current request object (flask.request). This variable is unavailable if the template was rendered without an active request context.
-
session: The current session object (flask.session). This variable is unavailable if the template was rendered without an active request context.
-
get_flashed_messages(): The flask.get_flashed_messages() function.
we'll be covering these as part of flask over the next few weeks.
jinja objects
all of the basic Python data structures, such as variables, objects, lists, and dictionaries, can be understood by jinja and can be processed in a very similar way.
To output the result of a function in a template, just call the function as any regular Python function.
loops
- jinja includes 'if' and 'for' loops.
the format of for loops is like this:
{% for article in articles %}
<b>{{article.title}}</b><br />
<p>{{article.summary}}</p>
{% endfor %}
rss feeds
-
create a template that loops over the news items from the bbc's rss feed
-
you need to pass the articles to the template via render_template so it can loop over them
'if' statement
-
in jinja, 'if' statements take the form
{% if } {% endif %}
-
add an if statement to only display an rss feed if it contains a certain word
you can use
if <word> in article.summary
remember, words could have uppercase or lowercase letters. how do you make sure you only need to test for one case?
during the week...
create a small flask experiment of your own. include
- more than one route & view
- dynamic content
- use of jinja templates