09Flask
09Flask
https://drtnf.net/static/wordle.html
Server-side Rendering
• Server-side rendering listen for requests,
and uses python functions to build html
pages to return as a response.
• However, this mixes the logic and the
presentation.
• A typical pattern to use is to have a
template or views directory to have some
html that references objects and code, and a
rendering function that will take a template
and some data and builds the html
dynamically.
• Flask uses jinja for this task, but there are
many alternatives (pug, handlebars,
typescript)
Using Jinja
• We separate presentation and logic
by having a template directory to
contain annotated html, and specify a
rending function in the routes.py file
• When a request is received flask will
look for the matching template (in the
directory templates) and convert the
template to pure html using named
variables in the function.
• Two {{curly braces}} are used to
distinguish html from python
variables, and jinja does the
substitution
Jinja Loops and Conditionals
• Depending on the parameters
passed, we may want to display
the data differently.
• Jinja provides loops and
conditionals to allow the display
to adapt to data.
• For example, it is common to
pass in an array of objects, and
then present them in a table.
• Or we may want the display to
vary depending on who is
logged in.
Jinja Control Statements
• The syntax for control statements is to
use {% braces %}.
• Conditionals use if, else, elif, as
well as endif, since whitespace
scoping doesn’t work for html.
• We can also use for and while loops for
iterating through collections.
Jinja Inheritance
• Since we often want the titles, menus,
footers in an application to be the same,
we can have the templates inherit from
each other.
• The block xxxx is left unspecified for
other templates to fill in, and they can
extend the ase template by just
specifying how they would fill in xxxx
l This principle is
refered to as DRY:
dont repeat yourself
Forms
• To build PUT requests,
we typically use forms.
Flask uses the
WTForms module to Flask apps should have a secret key
validate Post Requests to protect against cross site request
forgery (CSRF). You can set in
• Install flask-wtf with app.py, but there are better ways.
pip and create a new
file in app, forms.py
• There are three parts to
the form: the form class,
the template containing
the form, and the route
for processing the form.
Rendering Forms
• Jinja works with flask-wtf to put
the appropriate input elements
in the page.
• The form.hidden_tag() is used
to protect against CSRF attacks
• The form elements are defined
by the forms.py class
• Attributes can be appended to
the elements in brackets.
• If a form doesn’t validate, the
errors are accessible in a list,
but are rendered server side.
Faster client side validation can
be applied using javascript.
• The url_for()maps back from the
function name to the route.
Processing Forms
• To process a form, we configure a
route for the POST method.
• We define an instance of the form
class, for both rendering and wrapping
posted data.
• A GET request won’t validate, so it will
jump to the last line, and render the
page.
• If a POST request validates, a flash
message is created, and the page is
redirected to the index.
• The flash messages are just a list that
can be accessed by other pages.
• To actually check a users passwords,
we need a database (next lecture).
App Configuration
• Storing the secret key in a source file isn’t
a good idea. Secret keys and user
credentials should always be manually
configured, and never part of the
repository. Setting them as system
variables is a good approach.
• Create a configuration file to store all
configuration variables. This can then be
loaded when the app runs.
• The environment variables can also store
database locations and credentials, and
keys for third party services
Debugging and the Flask Shell
• The Flask shell is a useful
way to test small functions
and their integration with
flask, without using a
browser.
• It loads the flask app, and all
the dependencies, but
doesn’t need the server
running. You can set the
shell context to have
variables predefined when
you start the shell.
• Debug mode is also very
useful. Set the system
variable FLASK_DEBUG=1
to get a trace of the errors
when the server crashes.
Suggested Reading