Sim Mautner
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Versions and GitHub Sync Note Insights Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       owned this note    owned this note      
    Published Linked with GitHub
    Subscribed
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    Subscribe
    --- title: 5.3 Web Apps Servers and Flask tags: COMP1010-22T1 slideOptions: transition: slide --- <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. * 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. --- ## Simple Calculator: Flask App * Write a Flask application with a two web pages: * The first page should get the information from the user: * Ask the user to enter 2 numbers and a symbol. For example `3 + 4` or `7 * 8`. * The second page should display the result of the calculation. --- ## 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 Simple Calculator application so that the user can press "Calculate" and be taken to the next web page displaying the result. --- ## 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 which numbers and symbols the user entered. * Calculate the result. * And send the updated HTML. <br> ### How do we do this? --- ## 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'] ``` --- # Project Starter Code Now go take a look at your project starter code. Does it make sense? Do you have any questions about it? --- ## 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) --- ## Limitations So Far * At this point we can only view the data that is submitted through the current form. * For example: * what if we wanted to save and display all the calculations the user has made on our calculator? * what if we wanted to save and display (or analyse data about) all the calculations anyone has ever made on our calculator? * We will learn how to do this in our next 2 topics: * Cookies * Saving Files on the Server --- ## Global Variables * A way to store this data. * Opens our code up to lots more errors. * A stepping-stone to using Cookies and Files. * MUST NOT BE SUBMITTED IN ANY COMP1010 WORK. (If you get global variables working, but can't transition them to Cookies or Files, please ask your tutor or myself for help.) --- ## 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 | --- ## 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/) ---

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully