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
This is an old version of this page. You can view the most recent version or browse the history.

lab 13

is52027c lab 13

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

wtforms

note: my version of this in the oab-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 a 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

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