<style> .reveal { font-size: 27px; } .reveal div.para { text-align: left; } .reveal ul { display: block; } .reveal ol { display: block; } img[alt=drawing] { width: 200px; } </style> # COMP1010 ## 5 Web Application Development ### 5.3 Web Servers and Flask --- ## Recap * Previously on COMP1010: * 5.0 Overview: we discussed the role of web browsers and web servers in running a web application. * 5.1 HTML: we learnt how to write HTML to create a web page. * 5.2 PyHTML: we learnt how to create HTML quickly and accurately using PyHTML. * But: * Our forms don't do anything. * We can't go from one web page to another. --- ## Warning - It Might Seem Like a Lot * This lecture looks like it has a lot of information. * It might seem overwhelming at first. <br> ### BUT... * After this lecture, you will be able to copy-paste generic Flask server code and (because you understand what each line means) make the appropriate changes to make your application run. * So don't worry about being able to write any of this from scratch. Just understand what it does so you can adapt it to your own project. --- ## Generic Flask Application Code ```{python} from flask import Flask, request from pyhtml import html # TODO add imports app = Flask(__name__) @app.route('/', methods=["GET", "POST"]) def homepage(): if request.method == 'POST': # TODO you received form data, handle it # (usually produce HTML) else: # TODO you didn't receive form data # (usually produce HTML) response = html( # TODO put your pyhtml code here ) return str(response) if __name__ == "__main__": app.run(debug=True) ``` --- ## Your Goal * Your goal in this lecture, is to learn to understand the different parts of this code so that you can copy and paste it and then: * insert your own code instead of the TODOs (mostly pyhtml to produce the content specific to your application) * add more routes and functions (by copying the one already there and adjusting it to work for your application) --- ## Let's start from the beginning... --- ## Flask: A Simplest Application ```{python} from flask import Flask app = Flask(__name__) @app.route('/') def homepage(): return "Hello World!" if __name__ == "__main__": app.run(debug=True) ``` --- ## Understanding the Application ### Things we already know: * Checking if this file is the one to run before doing anything: (covered in topic 4) ```{python} if __name__ == "__main__": ``` * A function which returns "Hello World!" (Which can be interpretted as a very simple web page) (covered in topic 3.2.5) ```{python} def homepage(): return "Hello World!" ``` --- ## Understanding the Application ### New things: * importing Flask (still quite familiar) ```{python} from flask import Flask ``` * creating a Flask object ```{python} app = Flask(__name__) ``` * running the Flask object ```{python} app.run(debug=True) ``` These allow us to use the Flask framework to do a lot of "behind the scenes" work. --- ## Understanding the Application: Routes * To fully understand the line `@app.route('/')` we need to add a few more **routes**. * Each route is associated with a function. (It needs be to created in the line above the function it is associated with.) ```{python} from flask import Flask app = Flask(__name__) @app.route('/') def homepage(): return "Hello World!" @app.route('/another_route') def some_other_function(): return "This is the webpage associated "+ \ "with <code>another_route</code>." @app.route('/list_desserts') def desserts(): return "Cake, Popcorn, Brownies" if __name__ == "__main__": app.run(debug=True) ``` --- ## Flask: A Simplest Application * Now have a read through the code and check you understand each step ```{python} # import Flask from flask import Flask # create the Flask app app = Flask(__name__) # declare a route and link it to a function @app.route('/') def homepage(): # return HTML from the function --> this will show up when that route is navigated to return "Hello World!" # if this file has been run, then run the Flask app if __name__ == "__main__": app.run(debug=True) ``` --- ## Note: Simplest Application * The examples above produce very simple HTML. * I've done this because I want you to get familiar with the Flask elements without being overwhelmed by PyHTML. * So let's take some time to write a more complex one. --- ## Guess My Number: Flask App * Write a Flask application with a two web pages: * The home page should: * Display the start of a game, telling the user to pick a number between 1 and 100 and not share it, and that it will guess numbers and the user will have to tell it `H` for higher, `L` for lower or `C` for correct. * Have a `Start Playing` button for the user to indicate that they have chosen their number and are ready to play. * The game page should: * Display a guess as to what the user's number is. * Have an input text box to allow the user to enter H, L or C. * Have a button to confirm when the user has entered their response. * Nice to have: a drop down menu instead of a textbox so the user can't accidentally input a value other than the expected ones. --- ## HTTP Request Methods * Now that we know how to create different web pages under different routes, we need to be able to move from one page to the next. * Hypertext Transfer Protocol (HTTP) is designed to enable communications between clients and servers. * A client (browser) sends an HTTP request to the server; then the server returns a response to the client. The response contains status information about the request and may also contain the requested content. * The two most common HTTP Methods: * GET * POST --- ## HTTP Request Methods: GET and POST * GET: * Is used to request data. * Should not be used when dealing with sensitive data. * So far we have used GET requests (they are the default when HTTP methods aren't specified for a route) to sent a request (the url) to the server and return the HTML to display. * POST: * Is used to send data to a server to create/update a resource. * An example of such data is the contents of a form which has been submitted. * The data sent to the server with POST is stored in the request body of the HTTP request. --- ## Getting to the Next Webpage ### Step 1: Tell the form where to go. * Forms: ```{python} form(action="destination_route")( # Other form elements input_(type="submit", value="Go") ) ``` * In the code above, when the `submit` is clicked, it will go to the `destination_route` function. --- ## Getting to the Next Webpage ### Step 2: Check that the destination route can handle POST requests. * The default request is GET, so until now we haven't had to specify anything to get a web page. * When a function is executed as a result of a form being submitted, it needs to specify that it is able to receive POST requests. --- * To enable only GET: ```{python} @app.route('/destination_route') ``` Or ```{python} @app.route('/destination_route', methods=["GET"]) ``` * To enable both GET and POST: ```{python} @app.route('/destination_route', methods=["GET", "POST"]) ``` * To enable only POST: ```{python} @app.route('/destination_route', methods=["POST"]) ``` --- * Now update your Guess My Number application so that: * when the user clicks `Start Playing` it goes from the home page to the game page. * when the user confirms their input on the game page it goes to the game page. --- ## Getting to the Next Webpage ### Step 3: Extract the data from the HTTP request in the destination. * Now when we go to the game page, we need to be able to find out whether the user specified `H`, `L` or `C` in response to our guess. * Then we can make our next guess. * And send the updated HTML. <br> ### How do we do this? --- ### Keeping Track of Data * Two types of data: * User's response: * `H`, `L` or `C` * Sent to the server through a form. * Other data needed: * `range_high`, `range_low`, `guess` * Lots of [options for different purposes](#Keeping-Track-of-Data-Within-the-Server) * For today, we will send it to the user in [hidden fields](https://www.w3schools.com/tags/att_input_type_hidden.asp) in the form, so that when they submit the form, we get it back in the server. --- ## Getting to the Next Webpage ### Step 3: Extract the data from the HTTP request in the destination. * Import request from Flask library. ```{python} from flask import Flask, request ``` * If we accept both GET and POST requests, we need to check if it was a POST (before we try and access the contents of the form). ```{python} if request.method == 'POST': ``` * Then we can access the details of what was in the form. For this, we need to know the `name` field of our form element. ```{python} my_variable = request.form['field_name'] ``` --- ## Finishing Guess My Number MVP * Add the following features to Guess My Number so that a full game can be played. * Now when we go to the game page, we need to be able to find out whether the user specified `H`, `L` or `C` in response to our guess. * Then we (the web server) can make our next guess. * And send the updated HTML. --- ## HTTP Responses * When we return HTML from our server, it's referred to as the HTTP response. * Flask also includes some information in it for the web browser. * HTTP status codes: * 2XX: Success (usually 200, meaning OK) * 4XX: Client Errors (often 404, meaning Not Found) * 5XX: Server Errors * A full list of HTTP status codes can be found [here](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes) --- ## Keeping Track of Data Within the Server * Hidden field (not secure from being seen and changed by the user) * Global variable (prevents our program from being stateless - more likely to have bugs in our code) * Cookies (great. We will learn this next. But not secure. Can be removed by the user by clearing cookies.) * File on our server (not great for speed with large data, otherwise good, will be covered in this course) * Database (good. not covered in this course.) * We also won't be covering security such as encryption in this course. --- ## Keeping Track of Data Within the Server | | Hidden Fields | Global Variables | Cookies | File on Server | Database | |---|:-:|:-:|:-:|:-:|:-:| Viewable by user | Y | | | | | Changeable by user | Y | | | | | Deletable by user | Y | | Y | | | Makes code more likely to have bugs (mistakes) | | Y | Expire | | | Y | Ease of implementation | Very Easy | Very Easy | Easy | Easy | Hard | Will be taught in COMP1010 | Y | | Y | Y | --- ## References * If you're interested in learning more and taking these skills further: * [Flask Quick Start Tutorial](https://flask.palletsprojects.com/en/2.0.x/quickstart/) * [Flask Tutorial](https://flask.palletsprojects.com/en/2.0.x/tutorial/) * [More about different types of HTTP requests](https://www.w3schools.com/tags/ref_httpmethods.asp) * [Someone else's articulation of why I believe global variables are evil. (And incidentally, an example of what can go wrong when producing HTML which using PyHTML would not allow to happen.)](http://swcarpentry.github.io/training-course/2012/11/claiming-a-topic-why-global-variables-are-a-bad-idea/) --- # Feedback ## Lecture: 5.3 Web Apps - Flask <iframe src="https://docs.google.com/forms/d/e/1FAIpQLSdVVDLLKPgq94xEP2PjHulbc_q-ZiR4pmY-9kb41IkVuh7-wg/viewform?embedded=true" width="640" height="400" frameborder="0" marginheight="0" marginwidth="0">Loading…</iframe> --- # Feedback ## Lecture: 5.3 Web Apps - Flask [https://forms.gle/Uod5Jpr7AJ2z7cHLA](https://forms.gle/Uod5Jpr7AJ2z7cHLA) ![](https://i.imgur.com/0L50D4L.png)
{"metaMigratedAt":"2023-06-16T11:42:17.765Z","metaMigratedFrom":"YAML","title":"5.3 Web Apps Servers and Flask","breaks":false,"slideOptions":"{\"transition\":\"slide\"}","contributors":"[{\"id\":\"969c3c3d-0ef4-4f08-b22a-2f2b8951224b\",\"add\":23240,\"del\":11171}]"}
    584 views