CS50x 2024 - Lecture 9 - Flask
CS50 Week 9 Overview
In this section, David J. Malan introduces CS50 Week 9, where the focus is on synthesizing various programming languages to create modern applications.
Synthesizing Programming Languages
- CS50 Week 9 focuses on combining Python, SQL, HTML, CSS, and JavaScript to create modern web and mobile applications.
- HTTP server has been used for serving web content but is limited to static content like HTML and CSS.
- Transitioning from websites to web applications involves handling user input via URLs for more interactivity.
- Understanding URLs as paths or routes in Flask allows for dynamic content generation beyond file names.
Introduction to Flask Framework
This section introduces Flask as a microframework popular in the Python world for building interactive web applications.
Flask Framework Introduction
- Flask simplifies web application development using Python compared to other frameworks like Django.
Lesson Structure and File Organization
In this section, the speaker discusses the standard file organization and naming conventions in Flask.
Standard File Organization
- Files and folders should have standardized names for better organization.
- The prescribed way in Flask includes having a Python program named app.py and a templates folder for HTML, CSS, and JavaScript files.
- Additional files like requirements.txt for third-party libraries and a static folder for images or static content are recommended.
Creating a Simple Web Application
This part covers setting up a basic web application using Flask.
Setting Up the Application
- Beginners should follow guidelines from documentation or tutorials to structure their applications correctly.
- The speaker demonstrates creating an index.html file with basic HTML structure including meta tags for mobile responsiveness.
- Emphasis on structuring the body of the webpage with static content before moving to dynamic inputs like user names.
Implementing Flask Functionality
Here, the focus is on incorporating Flask functionality into the web application.
Integrating Flask Features
- Importing necessary functions from Flask such as render_template and request in app.py to enable web application features.
- Defining the app variable using Flask function to treat app.py as a web application by specifying routes using @app.route().
Introduction and Setting Up the Web Application
In this section, the speaker introduces setting up a web application using Flask in Python.
Specifying Routes and Defining Functions
- The speaker specifies the route for implementing code and defines a function named index by default. This function returns "hello, world".
- The function app.route defines a route for the application where visiting "/" triggers the index function to be called.
Creating Folders and Moving Files
- A new folder named hello is created, and app.py along with templates are moved into it.
- Navigating through directories shows the creation of the hello folder containing app.py and a templates folder with index.html.
Running the Web Application
This section covers running the Flask web application and viewing it in a browser.
Running Flask Server
- Running
flask runturns app.py into a working web application.
- Accessing the provided URL opens the basic web application displaying "hello, world".
Viewing Page Source
- Inspecting page source reveals that only text is returned without valid HTML structure.
- Updating app.py to use render_template to display contents of index.html results in proper HTML rendering on reload.
Introducing Dynamic Features
The speaker introduces dynamic features by utilizing variables from HTTP requests in Flask.
Utilizing Request Variable
- Introducing request.args which contains key-value pairs from HTTP requests simplifies handling user input via URLs.
Implementing Templates
- Modifying index.html to include placeholders for dynamic content using Jinja syntax.
New Section
In this section, the speaker explains how to pass user input from an application to a template in Flask.
Passing User Input to Template
- The speaker creates a variable called
namein theindexfunction to store user input.
- The
argsdictionary in Flask automatically stores key-value pairs from the URL when a request is made.
- By using named parameters in Python, the speaker sets up a placeholder variable for dynamic content.
- Demonstrates dynamically updating content on a web page based on user input by changing the URL parameter.
Dynamic Content Generation
This part discusses how dynamic content is generated and served by Flask.
Dynamic Content Display
- Shows how dynamic content is displayed on the webpage based on user input.
- Explains the difference between static and dynamic applications through code examples.
Error Handling and Default Values
Error handling and setting default values for variables in Flask applications are covered here.
Error Handling and Defaults
- Discusses HTTP status codes, specifically focusing on error code 400 for missing parameters.
- Introduces defensive coding practices by setting default values for variables if certain conditions are not met.
Optimizing Code with Request Args
Optimizing code by using request.args.get() method instead of directly accessing dictionary keys.
Code Optimization
New Section
In this section, the speaker discusses the importance of naming variables appropriately in templates to avoid confusion.
Naming Variables in Templates
- It's recommended to name variables meaningfully rather than using generic placeholders. This practice enhances code readability.
- The speaker highlights the convention in Flask where variable names are often identical to the values passed in for visual convenience.
Implementing a Second Template
Here, the focus shifts towards implementing a second template and creating a user-friendly form for interaction.
Creating a User-Friendly Form
- Demonstrates replacing a simple greeting with an HTML form that uses the GET method for user interaction.
- Explains setting up form elements such as input fields and buttons with appropriate attributes like autocomplete and autofocus.
Creating Routes and Rendering Templates
This part covers setting up routes, handling user inputs, and rendering templates based on user actions.
Setting Up Routes and Rendering Templates
- Introduces creating a new route "/greet" to handle form submissions and render a new template called greet.html.
- Shows how to retrieve user input from forms using request.args.get() and pass it into rendered templates efficiently.
Finalizing Template Creation
The final steps involve creating a new template file based on user input data.
Completing Template Creation
- Guides on copying existing HTML code into a new file named greet.html within the templates folder for displaying personalized greetings.
New Section
In this section, the speaker discusses the URL changes and the existence of a new route in the web application.
Analyzing Web Application Design
- The design critique focuses on having duplicated content in multiple files.
- Duplicating code can lead to maintenance issues when changes are needed.
- Using templates in web frameworks like Flask helps avoid duplication and improves design.
- Introducing a layout.html file as a template for consistent design across pages.
New Section
This part delves into Jinja syntax and using templates to create placeholders for code blocks in web development.
Implementing Jinja Syntax
- Demonstrates using Jinja syntax to define blocks within HTML templates.
- Explains how Jinja allows for placeholders not just for variables but entire code blocks.
- Shows how to extend templates by inheriting from a base template and customizing specific blocks.
New Section
The focus here is on integrating templates into different files to streamline web page creation.
Integrating Templates
- Utilizes extends keyword in Jinja to inherit from a base template.
- Demonstrates inserting unique content into specific blocks within extended templates.
New Section
In this section, the speaker discusses the importance of design in web development and how to handle situations where boilerplate code needs customization.
Handling Design Changes
- Nothing has changed as it still works, but a better design has been implemented for easier customization.
- Google likely uses a more advanced version of this technique for consistent search result pages.
Design Considerations and URL Parameters
This part covers the significance of URL parameters in maintaining statefulness and privacy concerns related to sensitive information in URLs.
URL Statefulness and Privacy
- URLs being stateful allows easy sharing of links with dynamic content.
- Revealing sensitive data like credit card numbers or passwords in URLs poses privacy risks.
Transitioning from GET to POST Method
The speaker explains transitioning from using GET to POST method for improved security when handling sensitive data.
Implementing POST Method
- Changing the method from GET to POST enhances security by not exposing data in the URL.
- Specifying supported methods using square brackets in Python Flask's route function.
Utilizing Request Form for Enhanced Security
This part focuses on utilizing request.form over request.args for improved security when handling form submissions.
Enhancing Security with Request Form
- Switching from request.args to request.form ensures secure handling of form data.
- Using request.form instead of request.args when implementing post method improves privacy and security.
Phew, Other Questions?
In this section, the speaker addresses questions from the audience regarding supporting both GET and POST requests in an application.
Supporting GET and POST Requests
- The speaker decided to support only POST requests, simplifying the implementation.
- Demonstrates consolidating different functionalities into individual routes for more complex applications.
- Explains the importance of consolidating related functionality into a single route for better organization.
- Shows how to modify routes to support multiple methods like GET and POST efficiently.
Consolidating Functionality into One Route
This part focuses on consolidating related functionalities into a single route for better design and management.
Simplifying Routes
- Eliminates a specific route to consolidate functionality into one main route.
- Demonstrates using methods equals "GET" or "POST" within the index route based on request.method.
- Illustrates processing form data differently based on whether it's a GET or POST request.
Fixing Form Submission Bug
The speaker addresses a bug related to form submission handling in the application.
Handling Form Submission
- Fixes a bug where submitting an empty form still displayed output incorrectly.
- Removes reliance on default values in app.py and introduces conditional logic in greet.html template.
- Implements conditional display of user input based on whether it is empty or not in the template.
Enhancing User Input Display
Enhancing user input display by adding conditional logic in templates for improved output presentation.
Conditional Logic Implementation
- Introduces conditional logic in Jinja template to display user input only if it is not empty.
New Section
In this section, the speaker introduces Jinja and demonstrates how to use conditional logic in Jinja templates.
Introduction to Jinja and Conditional Logic
- The speaker explains the syntax for using conditional logic in Jinja templates.
- Demonstrates a simple example of using if-else statements in a Jinja template to display different content based on conditions.
- Shows the outcome of applying conditional logic in a web application by displaying different greetings based on user input.
Web Development Journey
The speaker shares their experience with web development, starting from their early days creating web applications.
Early Web Development Days
- Describes creating their first web application during their sophomore year at Mather House.
- Recalls the manual process of registering for Freshman Intramural Sports at Harvard back in 1995.
- Talks about transitioning to web programming using Perl after taking CS50 in 1996.
Evolution of Web Applications
The speaker reflects on the evolution of web applications over time and discusses the technologies used in early web development.
Evolution of Web Technologies
- Mentions using Perl for web development and highlights the limitations faced due to lack of CSS.
- Explains using JavaScript for basic interactivity like changing images on hover.
Creating a Simple Web Application
The speaker begins creating a basic web application for registering first-year students for sports.
Setting Up the Application
- Initiates setting up a new folder named "froshims" for the application.
- Copies necessary files into the project directory and modifies layout.html for the new application structure.
Building Registration Page
The speaker starts building a registration page within the web application.
Developing Registration Form
- Creates an index.html file that extends layout.html and sets up basic structure with an h1 tag and form element.
Autocomplete and Dropdown Menu Implementation
In this section, the speaker discusses implementing autocomplete and a dropdown menu in HTML forms.
Autocomplete Field Setup
- The field is named "name" to ask for human names.
- Placeholder text is set as "Name".
- Field type is set as text.
Dropdown Menu Creation
- A dropdown menu in HTML is called a select menu.
- The input name for the dropdown menu is set as "sport".
- Options include basketball, soccer, and ultimate Frisbee.
Enhancing User Experience with Default Selection
This part focuses on improving user experience by setting default values in the form fields.
Setting Default Value for Dropdown
- Added an option at the top of the dropdown with no value but labeled as "sport".
- Users cannot select this default option but are encouraged to choose an actual sport.
Form Validation and Server-Side Logic
Discusses form validation and server-side logic implementation in app.py.
Implementing Form Validation
- Validate user input for name and selected sport.
- Use request.form.get to check if name field is filled.
Failure Handling and Validation
In this section, the speaker discusses failure handling and validation in a web application.
Implementing Quick Solutions
- Implement a quick solution to handle failures by assuming failure if the name field is empty.
Fixing Method Not Allowed Error
- Encounter a "Method Not Allowed" error due to restrictions in app.py.
- Modify the methods allowed in app.py to include POST requests.
Debugging and Refining the Application
This part focuses on debugging issues and refining the web application.
Identifying Internal Server Error
- Encounter an internal server error after fixing previous errors.
- Discuss how errors can escalate over time without proper handling.
Handling Response Errors
- Address missing response handling leading to invalid responses.
- Propose adding success or failure messages based on conditions.
Enhancing User Experience with Templates
Enhancing user experience through template rendering for success and failure scenarios.
Improving User Feedback
- Render appropriate HTML templates for success and failure responses instead of plain text.
Implementing Further Validation
Tightening up validation logic by simplifying conditional statements.
Streamlining Validation Logic
- Simplify conditional statements by combining similar checks into one line of code.
Creating Template Pages for Success and Failure
Creating template pages for success and failure messages to enhance user interaction.
Designing Template Pages
- Create separate HTML templates for success and failure messages to provide meaningful feedback to users.
Ensuring Data Integrity Through Validation
Ensuring data integrity by validating user inputs against predefined options.
Preventing Invalid Inputs
- Restrict user inputs to predefined options to maintain data integrity within the application.
New Section
In this section, the speaker discusses creating a Python list and using it to generate a form in Jinja.
Creating Python List for Form Generation
- The speaker creates a Python list with values for basketball, soccer, and ultimate Frisbee.
- Demonstrates setting up placeholders in Jinja templates by passing the list into the index.html template.
- Explains conventional ways of naming placeholders and variables to indicate constants in Python.
Using Jinja Placeholders
This part focuses on utilizing Jinja placeholders to dynamically populate options in a select menu.
Utilizing Jinja Placeholders
- Shows how to iterate over the sports list using Jinja syntax within an HTML template.
- Demonstrates inserting dynamic content into option elements using curly braces within the Jinja loop.
Form Validation and Security Measures
This section covers form validation and security measures to prevent unauthorized data input.
Implementing Form Validation
- Discusses specifying values for option elements in forms for better user experience without changing functionality.
- Emphasizes the importance of server-side validation to prevent potential security breaches or data pollution.
Preventing Unauthorized Data Input
Here, the focus is on preventing unauthorized data input through proper validation techniques.
Preventing Unauthorized Input
- Demonstrates checking user input against predefined lists to ensure only valid entries are accepted.
New Section
In this section, the speaker discusses the use of radio buttons and checkboxes in web development.
Understanding Radio Buttons and Checkboxes
- Radio buttons are mutually exclusive, while checkboxes are inclusive.
- Changing the input type from radio to checkbox allows for selecting 0 or more options.
- Adjusting validation in Python code to handle multiple checkbox selections.
- Ensuring all checked values are processed correctly using a loop in Python.
New Section
This part focuses on validating form inputs and handling errors in web development.
Form Validation and Error Handling
- Checking against each value that was checked on the form for validity.
- Resolving an attribute error related to dictionary attributes in Flask.
- Using
getlistmethod to retrieve all values from HTML checkboxes in Flask.
New Section
The speaker elaborates on processing user inputs and enhancing website functionality.
Processing User Inputs and Enhancing Functionality
- Registering user input with checkboxes and handling form data effectively.
- Leveraging building blocks in HTML and Flask for website customization.
New Section
In this section, the speaker discusses the process of registering registrants in an application and utilizing dictionaries to store key-value pairs efficiently.
Registering Registrants
- Utilizing dictionaries as a key-value pair for storing registrants' information.
- Exploring the structure of registrants.html template and its connection with the global dictionary.
- Demonstrating how the HTML table displays registrants' names and sports using Jinja loop.
- Redirecting users to the /registrants route after adding their information to the global dictionary.
Understanding Redirects and SQL
This section delves into understanding redirects in Flask applications and introduces the concept of using SQL for data persistence.
Redirect Mechanism
- Analyzing how redirects work by examining network requests and response headers.
- Implementing redirects in Flask using the
redirectfunction for seamless navigation between routes.
Introduction to SQL
- Highlighting the limitations of using global variables for data storage due to potential data loss scenarios.
New Section
In this section, the speaker demonstrates how to work with a SQLite database in Python using CS50's library.
Working with SQLite Database
- Import SQL function from CS50's library for SQLite database interaction.
- Open and view the structure of an empty database file called froshims.db using sqlite3.
- Access the SQLite database in app.py to interact with it.
- Insert rows into the database table using CS50's library and avoid injection attacks by using question marks for user input.
New Section
This part focuses on displaying data from the SQLite database in a web application using Jinja templates.
Displaying Data in Web Application
- Select all registrants from the database and pass them to a Jinja template for display.
- Modify the Jinja template (registrants.html) to include additional columns like deregister button.
New Section
The speaker demonstrates how primary keys are used to uniquely identify records in a web application.
Using Primary Keys
- Register users in the web application and assign auto-incrementing primary keys for each record.
- Illustrate how primary keys are crucial for uniquely identifying records when interacting between browser and server.
New Section
This part covers handling deregistration functionality based on primary key identifiers.
Handling Deregistration
- Submitting deregistration requests by passing primary key identifiers through hidden inputs in forms.
Implementing Froshims
In this section, the implementation of a system to register and deregister users for a sport is discussed using the Model View Controller (MVC) paradigm.
MVC Paradigm
- MVC stands for Model View Controller.
- Model stores data, view displays content, and controller manages logic.
- Components of web applications are identified based on MVC principles.
Web Application Login Process
This section covers how web applications manage user login sessions using cookies and server-side storage.
User Login Sessions
- When logging in, the server sends a response confirming authentication.
- Servers use cookies with unique identifiers to remember logged-in users.
- Set-Cookie header instructs browsers to store session information.
Maintaining State in Web Applications
The importance of cookies in maintaining state between clients and servers in web applications is explained.
Importance of Cookies
- Cookies enable websites to be stateful by storing user-specific information.
- Browsers remind servers of stored cookies during subsequent interactions.
Functionality of Cookies
The functional role of cookies in web applications is detailed.
Functionality Explanation
Introduction to Cookies and Tracking
In this section, the speaker discusses the use of cookies for tracking and advertising purposes, highlighting how clearing cookies can reset identifiers.
The Role of Cookies in Tracking
- Cookies are extensively used for advertising and tracking purposes.
- Browsers habitually send unique identifiers to websites, even in incognito mode.
Clearing Cookies and Tracking
- Clearing cookies or closing incognito windows resets identifiers, making users appear different.
- Servers can still track users based on IP addresses and browser configurations despite efforts to remain anonymous.
Implementing User Sessions with Flask
This section delves into leveraging Flask's session management capabilities to handle user logins effectively.
Setting Up Session Management in Flask
- Flask provides a global variable for managing sessions akin to a shopping cart.
- Configuration steps involve setting session permanence and type for effective session handling.
Implementing User Login Functionality
- Demonstrates creating a login form using Flask's render template function.
New Section
In this section, the speaker discusses handling user login functionality in the app.py file by utilizing session variables to store user information securely.
Handling User Login
- The session variable is a dictionary that stores user information securely. It ensures unique data for each user visiting the website.
- Storing user input from the login form into the session variable allows for personalized experiences on the website.
- After storing the user's name in the session, a redirect is used to send them back to the home page to confirm successful login.
- Retrieving and displaying the stored name from the session variable in subsequent visits allows for personalized content based on who is logged in at that moment.
Improving User Interface
This part focuses on enhancing user experience by providing clear navigation options for logging in and out of the website.
Enhancing UI with Login and Logout Links
- Adding a link to /login on index.html improves usability by guiding users to log in easily.
- Including a /logout link, even if not functional yet, prepares for future logout functionality and enhances UI design.
- Clicking on login redirects users to a simple form where they can enter their name for login purposes.
Setting Up a Basic E-commerce Store
In this section, the speaker demonstrates setting up a basic e-commerce store resembling an early version of Amazon.
Creating a Simple Online Store
- The initial version of the store resembles Amazon 1.0, selling only five books.
- Unique IDs hidden in forms are used to add items to the cart.
- Files and folders in the project directory include app.py, requirements.txt, templates, and store.db for storing session data.
Understanding Website Primitives
This part delves into understanding how websites function using basic building blocks.
Analyzing Website Structure
- Forms with unique IDs are utilized to add items to the cart.
- The database table "books" contains book titles.
Exploring Database Setup
Here, the speaker explores the database setup for storing information about books.
Database Configuration
- The database table "books" consists of ID and title columns.
- Data is retrieved from the database using SQL queries and displayed on the website.
Implementing Dynamic Content Display
This section focuses on dynamically displaying content on web pages based on database entries.
Rendering Web Pages Dynamically
- Python code fetches data from the database to display all available books on the webpage.
Utilizing SQL Queries for Data Retrieval
Demonstrating how SQL queries are used to retrieve data from databases in Python applications.
Querying Databases with SQL
- SQL queries return lists of dictionaries representing database entries.
Managing Shopping Cart Functionality
Explaining how shopping cart functionality is implemented within the web application.
Handling Shopping Cart Operations
How Redirects Work
In this section, the speaker explains how redirects work in web development.
Understanding Redirects
- Redirects in web development send requests back via GET even if they were initiated by POST.
- Using parentheses and a question mark in CS50 library allows for placeholders to separate items via commas automatically.
- Demonstrates rendering a template (cart.html) with a simple structure including an h1 tag and an ordered list.
- Explains the concept of private URLs preventing multiple users from accessing the same cart simultaneously.
Session Management and Cookies
This part covers session management and cookies in web applications.
Session Handling
- Discusses how servers manage sessions using unique cookies for individual users.
- Explains how browsers and servers establish new sessions when visiting a website for the first time.
- Details the process of setting cookies by servers to track users individually.
Flask Implementation
The speaker delves into Flask's role in automating server-side processes like session management.
Flask Automation
- Highlights Flask's automation of cookie handling through imported configurations, simplifying web application development.
New Section
The speaker discusses the presence of multiple offices and databases, exploring the intersection of SQL and Python.
Exploring Multiple Offices and Databases
- The speaker mentions the American office, UK office, and other prior offices in different years.
- Demonstrates accessing data from a database using SQLite commands.
- Shows how to manipulate SQL data in Python by utilizing dictionaries.
- Discusses enhancing search functionality by implementing wildcard searches securely.
Enhancing Search Functionality
The speaker demonstrates improving search functionality by incorporating wildcard searches securely using placeholders.
Implementing Wildcard Searches Securely
- Advises against using Python f-string for wildcard searches.
- Demonstrates concatenating strings with placeholders for secure wildcard searches.
- Shows how to enhance search functionality to provide broader matches while ensuring user input security.
Introduction to AJAX for Web Development
The speaker introduces AJAX as a technique for web development to enhance user experience without page reloads.
Introducing AJAX for Modern Web Development
- Explains the concept of AJAX (Asynchronous JavaScript And XML) for dynamic data retrieval.
- Highlights how AJAX prevents full page reloads, providing a seamless user experience.
Notice of Autocomplete Functionality
The section discusses the modern autocomplete feature using AJAX, which sends HTTP requests without reloading the entire page.
Understanding Autocomplete Functionality
- Autocomplete feature sends HTTP requests for data retrieval.
- Demonstrates how AJAX works by inserting data into an existing web page without full reload.
- Explains the initial empty ul element and its population through JavaScript code.
- Describes fetching data from the server based on user input asynchronously.
Working with API and JSON
This part delves into APIs, JSON, and their role in retrieving and displaying data efficiently.
API Integration and JSON Usage
- Fetching content from the server using fetch function in JavaScript.
- Updating ul element's inner HTML dynamically based on fetched data.
- Showing real-time changes in the web page as new data is retrieved.
- Introducing APIs as a standardized way to access external server data.
Transition to JSON Data Format
Transitioning from HTML-based responses to JSON format for efficient data handling.
Embracing JSON Data Format
- Explains the shift towards using JSON over HTML or XML for structured data exchange.
- Contrasting messy HTML responses with machine-readable JSON format for easier parsing.
Utilizing jsonify Function in Flask
Implementing jsonify function in Flask framework to convert data into JSON format efficiently.
Working with jsonify Function
How to Structure Data for Web Applications
In this section, the speaker discusses structuring data for web applications and demonstrates how to improve data presentation.
Structuring Data in Web Applications
- The speaker explains the process of escaping user input with wildcards and handling cases where no results are returned by providing an empty list.
- Demonstrates transitioning from using templates to directly jsonifying text for improved data transfer efficiency.
- Shows how the same functionality is maintained while enhancing standardization in data transmission over the internet.
- Discusses sending comprehensive data including titles, episode numbers, unique IDs, and more in a standardized format for efficient code utilization.
Modern Application Functionality
This part delves into modern application functionality and the underlying processes involved in delivering content efficiently.
Modern Application Functionality
- Explains how applications like Gmail constantly fetch and display new content through server responses containing JSON or other formats.
- Details the continuous updating of browser content with new emails appearing in the DOM as received from server responses.