Skip to content

GitLab

  • Menu
Projects Groups Snippets
    • Loading...
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in
  • L lab-exercises
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 2
    • Issues 2
    • List
    • Boards
    • Service Desk
    • Milestones
  • Merge requests 0
    • Merge requests 0
  • Deployments
    • Deployments
    • Releases
  • Monitor
    • Monitor
    • Incidents
  • Analytics
    • Analytics
    • Value stream
    • Repository
  • Wiki
    • Wiki
  • Activity
  • Graph
  • Create a new issue
  • Commits
  • Issue Boards
Collapse sidebar
  • data-networks-web
  • lab-exercises
  • Wiki
  • lab 13

Last edited by Dan McQuillan Jan 31, 2018
Page history

lab 13

is52027c lab 13.h

in this lab we're going to look at flask's request object, including

  • GET requests that pass some user input (i.e. a key/value pair in the url)
  • POST requests submitted via a form
  • basic validation
  • uploading a file
  • using flask's implementation of WTForms

task 1: adapting headlines for user input via GET

note: my version of this in the lab-13 repo is get_headlines.py

  • in this exercise, you will adapt your headlines project from the last lab to respond to user choices made via a GET request.
  • this means making use of flask's request object http://flask.pocoo.org/docs/0.12/quickstart/#the-request-object
  • you will implement a simple form that allows the user to choose which rss headlines to display; bbc, aljazeera or ap (associated press)

rss feeds

you can use these or find some of your own:

  • bbc: http://feeds.bbci.co.uk/news/rss.xml
  • aljazeera : https://www.aljazeera.com/xml/rss/all.xml
  • ap: http://hosted2.ap.org/atom/APDEFAULT/cae69a7523db45408eeb2b3a98c0c9c5

add a form

  • add a super simple form to your template that uses a text field to pass a value for 'publication'
  • you don't need to explicitly add method or action as they will defualt to 'GET' and 'POST' which is what we want

adapt the headlines view

  • get the value of 'publication' from request.args
  • fetch the headlines from that rss feed and pass them to the template
  • use a default value for the case where no choice is passed

note that

request.args['publication'] 

will throw a key error if no value was passed.

so it's better to use

request.args.get('publication')

you check it exists, then if it does assign that value to you 'publication' variable

task 2: mocking up a login form using POST

note: my version of this in the lab-13 repo is mock_login.py

  • in this task you are simply asked to mock up a login form in flask
  • you need a form that submits username & password via a POST request
  • you need to extract those values and check them against stored values (we will just use CONSTANTS in this case)

adding messaging

  • well designed user interactions display helpful messages when something hasn't gone right
  • flask helps you do this via 'message flashing' http://flask.pocoo.org/docs/0.12/quickstart/#message-flashing
  • there's an example of using this with a login process at http://flask.pocoo.org/docs/0.12/patterns/flashing/#message-flashing-pattern
  • you use get_flashed_messages() in the template to extract these messages for display
  • flash messages use flask's session features to pass the message between a request (e.g. login attempt) and the next request (e.g. redisplaying the form with a message)
  • for reasons which will be explained later, this means you need to set the value of app.secret_key (it can be anything!)

task: create helpful messages for cases where username / password are missing or wrong

task 3: uploading files

note: my version of this in the lab-13 repo is file_upload.py

  • the following script will upload image files to the directory 'static/uploads'.
  • you need to create that directory before running the script
  • create your own version of this script
  • work your way through each line in the upload_image view, making sure you understand what is going on

you should look up the path & listdir functions from the python standard library to check what they do:

  • https://docs.python.org/3.5/library/os.html
  • https://docs.python.org/3.5/library/os.path.html

you should also look up what secure_filename does: see the quickstart pages http://flask.pocoo.org/docs/0.12/patterns/fileuploads/

    from flask import Flask
    from flask import render_template, session, request
    from flask import redirect, url_for, flash
    from flask import send_from_directory
    import os
    from werkzeug.utils import secure_filename

    ALLOWED_EXTENSIONS = set(['png', 'jpg', 'jpeg', 'gif'])
    UPLOAD_FOLDER = 'static/uploads'

    app = Flask(__name__)

    app.secret_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'

    # defining allowed file types for file upload
    def allowed_file(filename):
        return '.' in filename and \
            filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

    @app.route('/')
    def index():
        files = [os.path.join(UPLOAD_FOLDER,f) for f in os.listdir(UPLOAD_FOLDER)]
        return render_template('upload_index.html', files=files)


    @app.route('/upload', methods = ['GET','POST'])
    def upload_image():
        if request.method == 'POST':
            if 'file' not in request.files:
                flash('no file part')
                return redirect(request.url)
            file = request.files['file']
            if file.filename=='':
                flash('no selected file')
                return redirect(request.url)
            if not allowed_file(file.filename):
                flash('file type not allowed')
                return redirect(request.url)
            if file and allowed_file(file.filename):
                filename = secure_filename(file.filename)
                file.save(os.path.join(UPLOAD_FOLDER,filename))
                flash('File "{}" successfully uploaded'.format(filename))
                return redirect(url_for('index'))
        return render_template('file_upload.html')    


    @app.route('/download/<filename>')
    def download_file(filename):
        print filename
        return send_from_directory(UPLOAD_FOLDER,
                                       filename)

    if __name__ == '__main__':
        app.run(debug=True,host='0.0.0.0',port=8000)          

task: rendering images

create a template to display your uploaded images

task 4: flask-wtforms extension

note: my version of this in the lab-13 repo is mock_login_wtforms.py

the flask extension flask-wtf implements the widely used python package, wtforms. this makes it easy to set up safe and user-friendly forms.

  • https://wtforms.readthedocs.io/en/latest/
  • https://wtforms.readthedocs.io/en/latest/

first you will need to install flask-wtf:

pip install --user Flask-WTF
  • task: review the quickstart docs for flask-wtf and see of you can figure out how to create and validate your mock login form this way
  • https://flask-wtf.readthedocs.io/en/stable/quickstart.html
  • the thing to remember is that flask-wtf helps you to generate the form and to validate it.
  • you can find a nice simple example / explanation at http://exploreflask.com/en/latest/forms.html
  • note that the second part ('rendering forms') is halfway down that page
  • don't worry about the csrf stuff at the moment! we'll go over that in the lectures

extension task: apply wtforms to file uploads

The snippets for achieving this are on https://flask-wtf.readthedocs.io/en/stable/form.html#module-flask_wtf.file

(Note that, currently, you do not have the Flask-Uploads extension installed).

keep developing this work during the week...

Clone repository
  • Home
  • lab 1
  • lab 12
  • lab 13
  • lab 14
  • lab 15
  • lab 17
  • lab 18
  • lab 2
  • lab 20
  • lab 3
  • lab 4
  • lab 5
  • lab 6
  • lab 7
View All Pages