Skip to main content

Unit - 4

TITLE

Flask Framework

1. Introduction to Flask & Web Development

1.1 Overview of Flask

1.1.1 Definition of Flask

Flask is a micro web framework for Python used to build web applications. It provides the essential tools required to handle web requests, responses, and routing, while allowing developers to add additional features as needed.

  • It is simple, flexible, and lightweight

  • Used for building:

    • Websites
    • APIs
    • Backend services

1.1.2 Flask as a Micro Web Framework

A micro framework means:

  • It provides only core functionalities:

    • Routing
    • Request handling
    • Response handling
  • It does not include built-in components like:

    • Authentication
    • Database ORM
    • Form validation

👉 Developers can add these using extensions

FeatureFlask (Micro)Full Framework (e.g., Django)
Built-in toolsMinimalMany
FlexibilityHighLimited
ComplexityLowHigher

1.1.3 Lightweight and Modular Nature

Flask is lightweight because:

  • Minimal core codebase
  • No unnecessary dependencies

Flask is modular because:

  • Features can be added as modules/extensions
  • Components are independent and replaceable

Example:

from flask import Flask

app = Flask(__name__)

@app.route('/')
def home():
return "Hello Flask"

👉 Only a few lines are enough to create a working web app.

1.1.4 Does Not Impose Many Dependencies

Flask does not force developers to use specific:

  • Databases
  • Libraries
  • Project structures

👉 You can choose:

  • SQLite / MySQL / PostgreSQL
  • Any frontend (HTML, React, etc.)
  • Any architecture

This makes Flask:

  • Highly customizable
  • Suitable for different project sizes

1.1.5 Flexibility and Developer Control

Flask gives full control to the developer:

  • You decide:

    • Project structure
    • Libraries to use
    • How components interact

Advantages:

  • Easier to build custom systems
  • No restrictions like full-stack frameworks
  • Better for experimentation and learning

1.1.6 “Batteries Not Included” Concept

Flask is often described as:

“Batteries Not Included”

Meaning:

  • It provides only basic tools
  • Additional features must be added manually

Examples of things NOT included by default:

  • Authentication system
  • Admin panel
  • ORM (Object Relational Mapping)

👉 These are added using extensions:

  • Flask-Login → authentication
  • Flask-Mail → email
  • SQLAlchemy → database ORM

1.2 Core Components of Flask

Flask is built on two major components:

1.2.1 Werkzeug

1.2.1.1 Definition (WSGI Toolkit)

Werkzeug is a WSGI (Web Server Gateway Interface) toolkit.

  • It acts as the backend engine of Flask

  • Handles communication between:

    • Web server
    • Python application

👉 It provides low-level utilities for web handling

1.2.1.2 Request Handling

Werkzeug handles incoming HTTP requests:

  • Parses:

    • URL
    • Headers
    • Form data
  • Converts raw HTTP data into Python objects

Example:

from flask import request

@app.route('/login', methods=['POST'])
def login():
username = request.form['username']
return f"Hello {username}"

👉 request object is powered by Werkzeug

1.2.1.3 Response Handling

Werkzeug also manages outgoing responses:

  • Converts Python return values into HTTP responses

  • Handles:

    • Status codes (200, 404, etc.)
    • Headers
    • Content

Example:

from flask import Response

@app.route('/')
def home():
return Response("Welcome", status=200)

1.2.2 Jinja2

1.2.2.1 Definition (Templating Engine)

Jinja2 is a templating engine used in Flask to generate dynamic HTML.

  • Allows embedding Python-like logic inside HTML

  • Separates:

    • Backend logic
    • Frontend presentation

1.2.2.2 Dynamic HTML Rendering

Jinja2 enables dynamic content rendering:

  • Variables
  • Conditions
  • Loops

Example:

<h1>Hello {{ name }}</h1>

Flask code:

from flask import render_template

@app.route('/user/<name>')
def user(name):
return render_template('user.html', name=name)

👉 Output:

Hello John

🧠 Diagram: Flask Architecture

2. Basic Flask Application

2.1 Creating Flask Application

2.1.1 Importing Flask Module

To start working with Flask, the first step is to import the Flask class from the flask package.

from flask import Flask
  • Flask is the core class used to create a web application instance

  • This import gives access to:

    • Routing
    • Request handling
    • Response handling

2.1.2 Creating App using Flask(name)

After importing Flask, we create an application instance:

app = Flask(__name__)
  • app is the main Flask application object
  • All configurations, routes, and logic are attached to this object

2.1.3 Meaning of name

__name__ is a special Python variable.

  • If the file is executed directly → __name__ = "__main__"
  • If imported as a module → __name__ = module_name

👉 Why Flask uses it:

  • Helps Flask determine:

    • Project root directory
    • Location of templates and static files

2.2 Defining Routes

2.2.1 @app.route() Decorator

The @app.route() decorator is used to define URL routes.

@app.route('/')
def home():
return "Home Page"
  • It tells Flask:

    • When a user visits '/', run the home() function

2.2.2 Mapping URLs to Functions

Routing connects:

  • URL → Python function

Flow:

Example:

@app.route('/about')
def about():
return "About Page"
  • /about → executes about()

2.2.3 Root URL (‘/’) Handling

  • '/' represents the home page
  • It is the default entry point of the web application

Example:

@app.route('/')
def home():
return "Welcome to Flask App"

👉 Visiting http://localhost:5000/ will show the output

2.3 Returning Response

2.3.1 Returning Strings

Flask allows returning simple strings as responses:

@app.route('/')
def home():
return "Hello World"
  • Flask automatically converts string → HTTP response

2.3.2 Displaying Output in Browser

When a route function returns data:

  • Flask sends it as an HTTP response
  • Browser displays it as a web page

Flow:

2.4 Running Flask Application

2.4.1 if name == "main"

This condition ensures the app runs only when the file is executed directly.

if __name__ == "__main__":
app.run()
  • Prevents execution when imported as a module
  • Standard Python practice

2.4.2 app.run() Method

app.run() starts the Flask development server.

app.run()

Default behavior:

  • Runs on: http://127.0.0.1:5000/
  • Starts a local server

2.5 Debug Mode

2.5.1 debug=True Configuration

Debug mode is enabled using:

app.run(debug=True)
  • Activates development features
  • Useful during coding phase

2.5.2 Auto Reloading Server

  • Server automatically restarts when code changes
  • No need to manually restart

👉 Saves development time

2.5.3 Detailed Error Messages

  • Displays full error trace in browser
  • Helps in debugging quickly

Example:

  • Shows:

    • Line number
    • Error type
    • Stack trace

Debug mode should NOT be used in production because:

  • Exposes internal details
  • Security risk (can reveal sensitive data)
  • Allows code execution in some cases

🧠 Complete Basic Flask App Example

from flask import Flask

app = Flask(__name__)

@app.route('/')
def home():
return "Home Page"

@app.route('/user/<name>')
def user(name):
return f"Hello {name}"

if __name__ == "__main__":
app.run(debug=True)

🎯 Key Points (Exam Focus)

  • Flask app created using Flask(__name__)

  • __name__ helps locate resources

  • @app.route() maps URL → function

  • '/' is root route

  • Functions return response (string/HTML)

  • app.run() starts server

  • Debug mode:

    • Auto reload
    • Detailed errors
    • Not for production

3. Virtual Environment Setup

3.1 Concept of Virtual Environment

3.1.1 Definition

A Virtual Environment is an isolated environment in Python used to manage project-specific dependencies.

  • It allows each project to have its own set of libraries
  • Works independently of the system-wide Python installation
  • Ensures clean and controlled development

👉 In Flask projects, virtual environments are used because:

  • Flask is not part of the standard library
  • It must be installed separately for each project

3.1.2 Isolation of Dependencies

A virtual environment ensures that:

  • Libraries installed in one project:

    • Do not affect other projects
  • Each project can have:

    • Different versions of the same library

Example:

ProjectFlask Version
Project AFlask 2.0
Project BFlask 3.0

👉 Both can run without conflict because of isolation

3.1.3 Avoiding Conflicts Between Projects

Without virtual environments:

  • Installing/upgrading a library may break another project

With virtual environments:

  • Each project is self-contained
  • No dependency conflicts

Benefits:

  • Clean dependency management
  • Easy debugging
  • Better project portability

🧠 Diagram: Virtual Environment Isolation

3.2 Installation Steps

3.2.1 Installing virtualenv

Install the virtual environment tool using pip:

pip install virtualenv
  • Installs the virtualenv package globally
  • Required to create isolated environments

3.2.2 Creating Virtual Environment

Create a new virtual environment:

virtualenv venv
  • venv → name of the environment folder

  • Creates:

    • Python interpreter copy
    • Site-packages directory

Project structure after creation:

project/

├── venv/
│ ├── bin/ or Scripts/
│ ├── lib/
│ └── ...

3.2.3 Activating Virtual Environment (Linux/Mac)

source venv/bin/activate
  • Activates the environment
  • Terminal prompt changes (shows active env)

Example:

(venv) user@system:~$

3.2.4 Activating Virtual Environment (Windows)

venv\Scripts\activate
  • Activates environment on Windows
  • Same behavior as Linux/Mac

Example:

(venv) C:\project>

3.2.5 Installing Flask (pip install flask)

Once the environment is activated, install Flask:

pip install flask
  • Installs Flask only inside the virtual environment
  • Does not affect global Python installation

3.2.6 Deactivating Virtual Environment

To exit the virtual environment:

deactivate
  • Returns to system Python
  • Removes (venv) from terminal prompt

🔁 Workflow Summary

🎯 Key Points (Exam Focus)

  • Virtual environment = isolated Python environment

  • Prevents dependency conflicts

  • Each project can have different library versions

  • Steps:

    • Install virtualenv
    • Create environment
    • Activate
    • Install Flask
    • Deactivate
  • Flask must be installed inside the environment

4. Routing and Application Settings

4.1 Routing in Flask

4.1.1 Definition of Routing

Routing is the process of mapping a URL (Uniform Resource Locator) to a specific Python function in a Flask application.

  • It defines how the application responds to a client request
  • Each route corresponds to a unique URL endpoint

4.1.2 URL to Function Mapping

In Flask, routing connects:

  • URL → Function → Response

Flow:

Example:

@app.route('/about')
def about():
return "About Page"
  • Visiting /about triggers the about() function

4.1.3 @app.route() Decorator Usage

The @app.route() decorator is used to define routes.

@app.route('/')
def home():
return "Home Page"
  • It binds a URL to a function
  • Must be placed above the function definition

4.2 Static Routes

4.2.1 Definition

A static route is a fixed URL that does not change.

  • It always returns the same response
  • No variables are used in the URL

4.2.2 Example: '/'

The root route '/' represents the homepage.

@app.route('/')
def home():
return "Home Page"

4.2.3 Function Execution on Route Access

  • When the user visits the URL:

    • Flask executes the mapped function
  • Example:

    • Visiting / → calls home()

4.2.4 Output Display in Browser

  • The returned value is sent as an HTTP response
  • Browser displays it directly

Example output:

Home Page

4.3 Dynamic Routes

4.3.1 URL Variables (<variable>)

Dynamic routes allow passing values through the URL.

Syntax:

@app.route('/user/<username>')
  • <username> is a variable placeholder
  • Flask extracts the value from the URL

4.3.2 Passing Values to Functions

  • The variable in the URL is passed as a function argument
@app.route('/user/<username>')
def user(username):
return username

4.3.3 Example: /user/<username>

If user visits:

http://localhost:5000/user/John
  • username = "John"

4.3.4 Personalized Output Generation

Dynamic routes enable personalized responses:

@app.route('/user/<username>')
def user(username):
return f"Hello {username}"

Output:

Hello John

4.4 String Interpolation

4.4.1 f-String Syntax

Python f-strings are used for formatting strings dynamically.

Syntax:

f"Text {variable}"

4.4.2 Dynamic Value Injection into Response

Used to insert variables into response strings:

@app.route('/user/<name>')
def user(name):
return f"Welcome {name}"

👉 Makes responses:

  • Dynamic
  • Personalized

4.5 Application Settings

4.5.1 Debug Configuration

Debug mode is enabled using:

app.run(debug=True)

Features:

  • Auto reload server
  • Shows detailed errors

4.5.2 Secret Key Usage

Flask uses a SECRET_KEY for:

  • Session management
  • Security features (cookies, flash messages)

Example:

app.config['SECRET_KEY'] = 'your_secret_key'

👉 Important for:

  • Flash messages
  • Authentication systems

4.5.3 Database URI Configuration

Used to connect Flask to a database.

Example:

app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///database.db'
  • Defines database location
  • Used by ORM tools like SQLAlchemy

4.6 Full Flask Application

4.6.1 Combining Static Routes

@app.route('/')
def home():
return "Home Page"

@app.route('/about')
def about():
return "About Page"

4.6.2 Combining Dynamic Routes

@app.route('/user/<name>')
def user(name):
return f"Hello {name}"

4.6.3 Running Complete App

from flask import Flask

app = Flask(__name__)

@app.route('/')
def home():
return "Home Page"

@app.route('/about')
def about():
return "About Page"

@app.route('/user/<name>')
def user(name):
return f"Hello {name}"

if __name__ == "__main__":
app.run(debug=True)

🧠 Complete Flow Diagram

🎯 Key Points (Exam Focus)

  • Routing = URL → Function mapping
  • @app.route() defines routes
  • Static routes → fixed URLs
  • Dynamic routes → use <variable>
  • Values passed as function parameters
  • f-strings used for dynamic responses
  • SECRET_KEY → security feature
  • Database URI → DB connection
  • Debug mode → development only

5. URL Building & HTTP Methods

5.1 URL Building

5.1.1 Definition

URL Building in Flask is the process of dynamically generating URLs using the url_for() function instead of hardcoding them.

  • It links URLs to function names (endpoints)
  • Ensures correct URL generation even if routes change

5.1.2 Need for URL Building

URL building is needed because:

  • Hardcoding URLs makes applications fragile
  • Changing a route requires updating URLs everywhere
  • Helps maintain clean and scalable applications

Example problem:

# Hardcoded URL
<a href="/user/John">Profile</a>

👉 If route changes → code breaks everywhere

5.1.3 Problems with Hardcoded URLs

Hardcoded URLs cause:

  • ❌ Code duplication
  • ❌ Maintenance difficulty
  • ❌ Broken links when routes change
  • ❌ Tight coupling between frontend and backend

Example:

@app.route('/profile/<name>')
def profile(name):
return f"Hello {name}"

But HTML still uses:

<a href="/user/John">

👉 Mismatch → broken navigation

5.2 url_for() Function

5.2.1 Syntax

url_for(endpoint, **values)
  • endpoint → function name
  • values → parameters passed to URL

5.2.2 endpoint (Function Name)

The endpoint is the name of the function linked to a route.

Example:

@app.route('/home')
def home():
return "Home"
url_for('home')

Output:

/home

👉 Flask uses function name, not URL string

5.2.3 values (Dynamic Parameters)

Used to pass variables for dynamic routes.

Example:

@app.route('/user/<username>')
def user(username):
return f"Hello {username}"
url_for('user', username='John')

Output:

/user/John

5.2.4 Dynamic URL Generation

url_for() dynamically builds URLs at runtime.

Example:

@app.route('/profile/<name>')
def profile(name):
return f"Profile of {name}"

@app.route('/go')
def go():
return url_for('profile', name='Alice')

Output:

/profile/Alice

👉 URL is generated automatically based on route definition

🧠 URL Building Flow

5.3 Benefits of URL Building

5.3.1 Route Consistency

  • URLs always match route definitions
  • No mismatch between frontend and backend

5.3.2 Automatic Query Parameter Handling

url_for() can also handle query parameters:

url_for('search', q='flask', page=2)

Output:

/search?q=flask&page=2

👉 Automatically formats query strings

5.3.3 Easier Maintenance

  • If route changes → no need to update everywhere
  • Only change route definition

Example:

@app.route('/new_profile/<name>')
def profile(name):
return name

👉 url_for() will still generate correct URL

5.3.4 Template Integration

url_for() is commonly used inside HTML templates.

Example:

<a href="{{ url_for('home') }}">Home</a>

For static files:

<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">

👉 Ensures:

  • Correct linking
  • Dynamic resource loading

🎯 Key Points (Exam Focus)

  • URL Building = dynamic URL generation
  • Use url_for() instead of hardcoding
  • endpoint = function name
  • values = parameters for dynamic routes
  • Prevents broken links
  • Supports query parameters
  • Used in both Python code and templates

6. HTTP Methods

6.1 Introduction to HTTP Methods

6.1.1 Definition

HTTP Methods (also called HTTP verbs) define the type of operation a client wants to perform on a server.

  • They are part of the HTTP protocol

  • Used to communicate intent:

    • Retrieve data
    • Send data
    • Update data
    • Delete data

👉 In Flask, HTTP methods are used to control how routes handle requests.

6.1.2 Client-Server Interaction

HTTP methods define how a client (browser) interacts with a server (Flask app).

Flow:

Each request includes:

  • URL
  • Method (GET, POST, etc.)
  • Optional data (form, JSON)

6.2 Types of HTTP Methods

6.2.1 GET

6.2.1.1 Retrieve Data

  • Used to fetch data from the server
  • Does NOT modify server data

Example:

@app.route('/')
def home():
return "Welcome"

👉 Browser sends a GET request automatically when visiting a page

6.2.1.2 Default Method

  • GET is the default HTTP method
  • If no method is specified, Flask assumes GET

Example:

@app.route('/about')
def about():
return "About Page"

👉 No need to specify methods=['GET']

6.2.1.3 Use Case: Fetch Web Page

  • Loading a webpage
  • Retrieving information from server

Example:

  • Visiting:
http://localhost:5000/

👉 Sends a GET request

6.2.2 POST

6.2.2.1 Send Data to Server

  • Used to send data from client to server
  • Data is included in the request body

6.2.2.2 Create/Update Resources

  • Used when:

    • Creating new data
    • Updating existing data (in many cases)

6.2.2.3 Use Case: Form Submission

Common use:

  • Login forms
  • Registration forms

Example:

from flask import request

@app.route('/login', methods=['POST'])
def login():
username = request.form['username']
return f"Hello {username}"

👉 Data is sent securely in request body (not visible in URL)

6.2.3 PUT

6.2.3.1 Update Existing Resource

  • Used to update existing data on the server
  • Replaces the resource with new data

6.2.3.2 Use Case: Editing Record

Example:

  • Updating user profile
  • Editing database record

Example:

@app.route('/update/<id>', methods=['PUT'])
def update(id):
return f"Update record {id}"

👉 Typically used in APIs

6.2.4 DELETE

6.2.4.1 Remove Resource

  • Used to delete data from server

6.2.4.2 Use Case: Delete Database Entry

Example:

  • Delete user account
  • Remove product from database

Example:

@app.route('/delete/<id>', methods=['DELETE'])
def delete(id):
return f"Deleted record {id}"

🧠 HTTP Methods Comparison Table

MethodPurposeData SentUse Case
GETRetrieve dataURLFetch webpage
POSTSend dataBodyForm submission
PUTUpdate dataBodyEdit record
DELETERemove dataURL/BodyDelete record

🧠 HTTP Request Lifecycle

🎯 Key Points (Exam Focus)

  • HTTP methods define type of operation

  • GET → retrieve data (default)

  • POST → send data (forms)

  • PUT → update resource

  • DELETE → remove resource

  • GET requests:

    • Visible in URL
  • POST requests:

    • Data sent in body (more secure)
  • PUT & DELETE mainly used in APIs

7. Handling HTTP Methods in Flask

7.1 methods Parameter

7.1.1 Defining Allowed Methods in Route

Flask routes accept specific HTTP methods using the methods parameter in @app.route().

  • By default, Flask allows only GET
  • To handle other methods (POST, PUT, DELETE), you must explicitly define them

Syntax:

@app.route('/path', methods=['GET', 'POST'])

👉 This tells Flask:

  • Only these methods are allowed for this route

7.1.2 Example: ['GET','POST']

@app.route('/login', methods=['GET', 'POST'])
def login():
return "Login Page"
  • GET → display page
  • POST → process submitted data

7.2 request Object

The request object is used to access incoming request data.

from flask import request

7.2.1 request.method

Used to identify which HTTP method was used.

@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
return "Form Submitted"
return "Login Form"

7.2.2 request.form

Used to retrieve form data sent via POST request.

username = request.form['username']
  • Accesses data sent from HTML forms
  • Works like a dictionary

7.2.3 Accessing Form Data

Example:

@app.route('/submit', methods=['POST'])
def submit():
name = request.form['name']
return f"Hello {name}"

👉 Form input is sent from client → accessed using request.form

🧠 Request Handling Flow

7.3 Examples

7.3.1 Handling GET Request

@app.route('/')
def home():
return "Welcome Page"

👉 Default GET request

7.3.2 Handling POST Request

from flask import request

@app.route('/login', methods=['POST'])
def login():
username = request.form['username']
return f"Hello {username}"

👉 Handles data submitted via form

7.3.3 Form Submission Workflow

7.3.3.1 GET → Display Form

@app.route('/login', methods=['GET'])
def login():
return '''
<form method="POST">
<input name="username">
<input type="submit">
</form>
'''

7.3.3.2 POST → Process Input

from flask import request

@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
username = request.form['username']
return f"Welcome {username}"
return '''
<form method="POST">
<input name="username">
<input type="submit">
</form>
'''

👉 Same route handles both:

  • GET → show form
  • POST → process form

🧠 Form Workflow Diagram

7.4 Advanced Methods

7.4.1 PUT Request Handling

@app.route('/update/<id>', methods=['PUT'])
def update(id):
return f"Updated record {id}"
  • Used for updating resources
  • Mostly used in APIs

7.4.2 DELETE Request Handling

@app.route('/delete/<id>', methods=['DELETE'])
def delete(id):
return f"Deleted record {id}"
  • Used to remove resources
  • Common in REST APIs

7.5 Combining URL Building & HTTP Methods

7.5.1 Login Form Example

from flask import Flask, request, url_for

app = Flask(__name__)

@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
username = request.form['username']
return f"Hello {username}"
return f'''
<form method="POST" action="{url_for('login')}">
<input name="username">
<input type="submit">
</form>
'''

7.5.2 url_for() for Form Action

  • Used to dynamically set form action URL
url_for('login')

👉 Prevents hardcoding URLs

7.5.3 Handling GET & POST Together

  • Same route handles both methods
  • Controlled using request.method

Pattern:

@app.route('/route', methods=['GET', 'POST'])
def handler():
if request.method == 'POST':
# process data
pass
else:
# display form
pass

🎯 Key Points (Exam Focus)

  • methods parameter defines allowed HTTP methods
  • Default method = GET
  • request.method → identifies request type
  • request.form → accesses form data
  • GET → display page
  • POST → process data
  • Same route can handle both GET & POST
  • url_for() used to avoid hardcoded URLs
  • PUT & DELETE used mainly in APIs

8. Templates in Flask

8.1 Introduction to Templates

8.1.1 Definition

Templates are HTML files used to generate dynamic web pages in Flask.

  • They separate:

    • Backend logic (Python)
    • Frontend presentation (HTML)
  • Stored in a special folder named templates

👉 Instead of returning plain strings, Flask can render full HTML pages.

8.1.2 Dynamic HTML Generation

Templates allow dynamic content generation, meaning:

  • Same HTML structure
  • Different data displayed

Example:

<h1>Hello {{ name }}</h1>
  • {{ name }} is replaced with actual data at runtime

👉 Output changes based on input:

Hello John

8.2 Jinja2 Templating Engine

8.2.1 Embedding Python Expressions

Flask uses Jinja2 to embed Python-like expressions inside HTML.

  • Allows:

    • Variables
    • Conditions
    • Loops

Example:

<p>{{ 5 + 5 }}</p>

Output:

10

8.2.2 Syntax Basics

SyntaxPurpose
{{ }}Output variables
{% %}Control statements
{# #}Comments

Example:

<h1>{{ name }}</h1>

{% if age > 18 %}
<p>Adult</p>
{% endif %}

8.3 Template Concepts

8.3.1 Dynamic Content ({{ variable }})

Used to display data passed from Flask.

Example:

<h1>Welcome {{ username }}</h1>

Flask code:

from flask import render_template

@app.route('/user/<name>')
def user(name):
return render_template('user.html', username=name)

8.3.2 Control Statements

8.3.2.1 if Conditions

Used for conditional rendering.

{% if user %}
<p>Welcome {{ user }}</p>
{% else %}
<p>Please login</p>
{% endif %}

8.3.2.2 for Loops

Used to iterate over data.

<ul>
{% for item in items %}
<li>{{ item }}</li>
{% endfor %}
</ul>

Flask code:

@app.route('/list')
def list_items():
items = ["Apple", "Banana", "Mango"]
return render_template('list.html', items=items)

8.3.3 Template Inheritance

8.3.3.1 Base Template (base.html)

A base template defines common layout:

<!DOCTYPE html>
<html>
<head>
<title>{% block title %}{% endblock %}</title>
</head>
<body>
<header>My Website</header>

{% block content %}{% endblock %}

<footer>Footer</footer>
</body>
</html>

8.3.3.2 Child Templates

Child templates extend the base template:

{% extends "base.html" %}

{% block title %}
Home Page
{% endblock %}

{% block content %}
<h1>Welcome to Home</h1>
{% endblock %}

👉 Benefits:

  • Reuse layout
  • Avoid duplicate code
  • Maintain consistency

🧠 Template Inheritance Flow

8.4 Template Working

8.4.1 templates Folder Rule (Default Location)

Flask automatically looks for templates in:

project/

├── app.py
└── templates/
└── index.html

👉 Important rule:

  • Folder name must be exactly templates

8.4.2 render_template() Function

Used to render HTML templates.

from flask import render_template

@app.route('/')
def home():
return render_template('index.html')
  • Loads template from templates/ folder
  • Converts it into final HTML

8.4.3 Passing Data to Templates

Data is passed as keyword arguments.

@app.route('/user/<name>')
def user(name):
return render_template('user.html', username=name)

Template:

<h1>Hello {{ username }}</h1>

🧠 Template Rendering Flow

🎯 Key Points (Exam Focus)

  • Templates = HTML files for dynamic content
  • Stored in templates/ folder
  • Flask uses Jinja2 engine
  • {{ }} → variables
  • {% %} → logic (if, loops)
  • Template inheritance → reuse layout
  • render_template() → renders HTML
  • Data passed from Flask to template
  • Enables separation of logic and UI

9. Static Files in Flask

9.1 Introduction to Static Files

9.1.1 Definition

Static files are resources that do not change dynamically and are sent to the client as-is.

  • Served directly by Flask (or a web server in production)
  • Used to enhance UI/UX and functionality

Examples:

  • Stylesheets
  • Scripts
  • Images
  • Fonts

9.1.2 Types (CSS, JS, Images, Fonts)

TypePurposeExample
CSSStyling web pagesstyle.css
JavaScriptInteractivityscript.js
ImagesVisual contentlogo.png
FontsTypography.woff, .ttf

9.2 Static Folder Structure

9.2.1 Default static Folder Rule

Flask automatically serves static files from a folder named static at the project root.

project/

├── app.py
├── templates/
└── static/
  • Folder name must be exactly static
  • Flask internally maps it to /static/... URL path

9.2.2 Subfolders (css, js, images)

Organize static files into subfolders:

static/

├── css/
│ └── style.css
├── js/
│ └── script.js
└── images/
└── logo.png

Benefits:

  • Better organization
  • Easier maintenance

9.3 Linking Static Files

9.3.1 url_for('static', filename)

Use url_for() to generate paths to static files.

<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
  • 'static' → predefined endpoint
  • filename → relative path inside static/

9.3.2 Dynamic Path Generation

Flask dynamically builds correct paths:

<script src="{{ url_for('static', filename='js/script.js') }}"></script>

👉 Avoids hardcoding:

<script src="/static/js/script.js"></script>

9.4 Examples

9.4.1 CSS Styling

CSS file (static/css/style.css):

body {
background-color: lightblue;
}

HTML template:

<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">

9.4.2 JavaScript Execution

JS file (static/js/script.js):

console.log("JavaScript Loaded");

HTML template:

<script src="{{ url_for('static', filename='js/script.js') }}"></script>

9.4.3 Image Loading

HTML template:

<img src="{{ url_for('static', filename='images/logo.png') }}" alt="Logo">

9.5 Output Behavior

9.5.1 Styled Output (CSS Applied)

  • CSS modifies appearance:

    • Colors
    • Layout
    • Fonts

Example:

Page background becomes light blue

9.5.2 Image Rendering

  • Images are displayed directly in browser

Example:

Logo appears on webpage

9.5.3 Console Output from JS

  • JavaScript runs in browser
  • Output visible in developer console

Example:

JavaScript Loaded

🧠 Static File Flow

9.6 Combining Templates and Static Files

9.6.1 Complete Web Page Example

Flask App:

from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def home():
return render_template('index.html')

if __name__ == "__main__":
app.run(debug=True)

Template (templates/index.html):

<!DOCTYPE html>
<html>
<head>
<title>Flask Static Example</title>
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
</head>
<body>

<h1>Hello Flask</h1>

<img src="{{ url_for('static', filename='images/logo.png') }}">

<script src="{{ url_for('static', filename='js/script.js') }}"></script>

</body>
</html>

🧠 Combined Flow

9.7 Best Practices

9.7.1 File Organization

  • Use folders:

    • css/
    • js/
    • images/
  • Keep structure clean and readable

9.7.2 Use of url_for()

  • Always use:
{{ url_for('static', filename='...') }}
  • Avoid hardcoded paths

9.7.3 Template Inheritance

  • Combine static files with base templates

Example:

<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">

👉 Ensures:

  • Consistent styling
  • Reusable layout

9.7.4 Minification of Assets

  • Reduce file size of:

    • CSS
    • JavaScript

Benefits:

  • Faster loading
  • Better performance

🎯 Key Points (Exam Focus)

  • Static files = non-dynamic resources
  • Stored in static/ folder
  • Flask automatically serves static files
  • Use url_for('static', filename=...)
  • Types: CSS, JS, Images, Fonts
  • CSS → styling
  • JS → interactivity
  • Images → visual content
  • Never hardcode static paths
  • Organize using subfolders

10. Flask with Database Connectivity

10.1 Introduction

10.1.1 Need for Database Integration

Web applications need a database to store and manage data permanently.

Without a database:

  • Data is lost when the app stops
  • No user accounts, records, or history can be maintained

With a database:

  • Data is stored persistently

  • Applications can manage:

    • Users
    • Products
    • Transactions
    • Logs

👉 Flask connects to databases using external libraries.

10.1.2 Dynamic Data Handling

Databases enable dynamic web applications.

  • Content changes based on stored data

  • Example:

    • User login
    • Displaying user profile
    • Showing product lists

Flow:

10.2 Supported Databases

10.2.1 SQLite

  • Lightweight, file-based database

  • No server required

  • Best for:

    • Small applications
    • Development/testing

Example:

database.db

10.2.2 MySQL

  • Relational database system

  • Requires server setup

  • Suitable for:

    • Medium to large applications

Features:

  • High performance
  • Multi-user support

10.2.3 PostgreSQL

  • Advanced relational database
  • Highly scalable and robust

Features:

  • Supports complex queries
  • Used in enterprise applications

10.3 Database Libraries

10.3.1 sqlite3

  • Built-in Python module
  • Used for SQLite database
import sqlite3

10.3.2 SQLAlchemy (ORM)

  • ORM = Object Relational Mapping
  • Allows working with database using Python objects instead of SQL

Example:

from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy(app)

Advantages:

  • Easier to use
  • Database-independent

10.3.3 mysql-connector-python

  • Used to connect Flask with MySQL
import mysql.connector

10.3.4 psycopg2

  • Used for PostgreSQL connectivity
import psycopg2

10.4 Steps for Connectivity

10.4.1 Creating Database

First, create a database.

Example:

  • SQLite -> automatically created file (eg. database.db)
  • MySQL/PostgreSQL → created using SQL tools

10.4.2 Defining Schema

Schema defines:

  • Tables
  • Columns
  • Data types

Example:

CREATE TABLE users (
id INTEGER PRIMARY KEY,
name TEXT,
email TEXT
);

👉 Important step before storing data

10.4.3 Installing Libraries

Install required database libraries:

pip install flask_sqlalchemy

or

pip install mysql-connector-python

10.4.4 Configuring Flask App

Set database configuration inside Flask app:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)

app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///database.db'
db = SQLAlchemy(app)

10.4.5 CRUD Operations

CRUD = Create, Read, Update, Delete

Create (Insert Data)
new_user = User(name="John")
db.session.add(new_user)
db.session.commit()
Read (Fetch Data)
users = User.query.all()
Update (Modify Data)
user.name = "Alice"
db.session.commit()
Delete (Remove Data)
db.session.delete(user)
db.session.commit()

🧠 Database Interaction Flow

10.5 Advantages

10.5.1 Data Persistence

  • Data remains stored even after app stops
  • No data loss

10.5.2 Dynamic Content

  • Web pages update based on database data

  • Example:

    • User dashboard
    • Product listings

10.5.3 Secure Storage

  • Databases provide:

    • Access control
    • Data integrity
    • Encryption support

👉 More secure than storing data in files

🎯 Key Points (Exam Focus)

  • Databases enable persistent storage

  • Flask connects using libraries like:

    • sqlite3
    • SQLAlchemy
    • mysql-connector
    • psycopg2
  • SQLAlchemy = ORM (no raw SQL needed)

  • Steps:

    • Create DB
    • Define schema
    • Install libraries
    • Configure Flask
    • Perform CRUD
  • CRUD = Create, Read, Update, Delete

  • Benefits:

    • Data persistence
    • Dynamic content
    • Secure storage

11. Error Handling and Exceptions

11.1 Importance

11.1.1 Robust Applications

Error handling is essential for building robust and reliable applications.

  • Prevents application crashes
  • Ensures smooth execution even when errors occur
  • Handles unexpected situations gracefully

Without error handling:

  • App may crash
  • User experience becomes poor
  • Debugging becomes difficult

11.1.2 User-Friendly Errors

Instead of showing raw errors, Flask allows displaying user-friendly messages.

Example:

  • Instead of:
Internal Server Error
  • Show:
Something went wrong. Please try again later.

👉 Improves usability and professionalism

11.2 HTTP Error Handling

Flask provides built-in mechanisms to handle HTTP errors.

11.2.1 404 Error Handling

Occurs when:

  • User requests a page that does not exist

Example:

from flask import Flask

app = Flask(__name__)

@app.errorhandler(404)
def not_found(error):
return "Page Not Found", 404

👉 Triggered when invalid URL is accessed

11.2.2 500 Error Handling

Occurs when:

  • Internal server error happens (bug, exception)

Example:

@app.errorhandler(500)
def server_error(error):
return "Internal Server Error", 500

👉 Helps handle unexpected failures

11.2.3 @app.errorhandler()

Used to define custom error handlers.

Syntax:

@app.errorhandler(error_code)
def handler(error):
return response
  • error_code → 404, 500, etc.
  • Function handles the error

🧠 Error Handling Flow

11.3 Custom Exceptions

11.3.1 try-except Usage

Python try-except is used to handle runtime errors.

@app.route('/divide')
def divide():
try:
result = 10 / 0
return str(result)
except Exception as e:
return "Error occurred"
  • try → risky code
  • except → handles error

11.3.2 Application-specific Errors

Custom logic can handle specific cases:

@app.route('/user/<name>')
def user(name):
if name == "":
return "Invalid user"
return f"Hello {name}"

👉 Helps define application-specific rules

11.4 Logging

11.4.1 Logging Exceptions

Logging is used to record errors for debugging.

import logging

logging.basicConfig(level=logging.ERROR)

@app.route('/error')
def error():
try:
1 / 0
except Exception as e:
logging.error(str(e))
return "Error logged"
  • Stores error details
  • Useful for developers

11.4.2 Debugging Support

Flask supports debugging through:

  • Debug mode (debug=True)
  • Error logs
  • Stack traces

Benefits:

  • Faster issue detection
  • Easier troubleshooting

🧠 Logging Flow

🎯 Key Points (Exam Focus)

  • Error handling ensures robust applications
  • Provides user-friendly error messages
  • 404 → page not found
  • 500 → server error
  • @app.errorhandler() handles HTTP errors
  • try-except handles runtime errors
  • Logging records errors for debugging
  • Debug mode helps identify issues quickly

12. Flash Messages

12.1 Introduction

12.1.1 Definition

Flash messages are a way to send temporary messages from the server to the user.

  • Stored in the session temporarily
  • Displayed on the next request
  • Automatically removed after being shown

👉 Used to provide feedback after actions

12.1.2 Temporary Notifications

Flash messages are commonly used for:

  • Login success
  • Form submission confirmation
  • Error alerts
  • Warning messages

Example:

"Login Successful"
"Invalid Password"

12.2 Message Types

Flash messages can represent different categories of feedback.

12.2.1 Success

  • Indicates successful operation

Example:

"Account created successfully"

12.2.2 Error

  • Indicates failure or problem

Example:

"Invalid username or password"

12.2.3 Warning

  • Indicates caution or important notice

Example:

"Password is weak"

12.3 Functions

12.3.1 flash()

Used to create a flash message.

Syntax:

flash(message)

Example:

from flask import flash

@app.route('/login', methods=['POST'])
def login():
flash("Login Successful")
return "Done"

12.3.2 get_flashed_messages()

Used to retrieve and display flash messages.

Syntax:

get_flashed_messages()

🧠 Flash Message Flow

12.4 Implementation Steps

12.4.1 Setting SECRET_KEY

Flask requires a SECRET_KEY to use sessions (and flash messages).

app.config['SECRET_KEY'] = 'your_secret_key'

👉 Required for:

  • Session storage
  • Security

12.4.2 Creating Messages

Use flash() inside a route:

from flask import Flask, flash

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret'

@app.route('/submit')
def submit():
flash("Form submitted successfully")
return "Submitted"

12.4.3 Displaying in Templates

Flash messages are displayed using Jinja2:

{% with messages = get_flashed_messages() %}
{% if messages %}
<ul>
{% for message in messages %}
<li>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
{% endwith %}

👉 This block:

  • Retrieves messages
  • Loops through them
  • Displays each message

🧠 Complete Example

from flask import Flask, flash, render_template

app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret'

@app.route('/')
def home():
flash("Welcome to the site!")
return render_template('index.html')

if __name__ == "__main__":
app.run(debug=True)

🎯 Key Points (Exam Focus)

  • Flash messages = temporary notifications
  • Stored in session
  • flash() → create message
  • get_flashed_messages() → retrieve messages
  • Requires SECRET_KEY
  • Used for success, error, warning messages
  • Displayed in templates using Jinja2

13. Working with Emails (Flask-Mail)

13.1 Introduction

13.1.1 Purpose

Flask-Mail is an extension used to send emails from a Flask application.

  • Enables email functionality inside web apps
  • Integrates with SMTP (Simple Mail Transfer Protocol) servers
  • Useful for user communication and notifications

👉 It allows Flask apps to interact with email servers like:

  • Gmail SMTP
  • Outlook SMTP
  • Custom mail servers

13.1.2 Use Cases (Verification, Reset)

Common use cases:

  • Account verification emails
  • Password reset emails
  • Notifications (alerts, updates)
  • Contact form messages

Example:

"Verify your email address"
"Reset your password"
"New login detected"

13.2 Installation

13.2.1 pip install Flask-Mail

Install Flask-Mail using pip:

pip install Flask-Mail
  • Adds Flask-Mail extension to your project
  • Required before using email features

13.3 Configuration

Flask-Mail requires configuration of mail server settings.

13.3.1 MAIL_SERVER

Defines the email server.

Example:

app.config['MAIL_SERVER'] = 'smtp.gmail.com'

13.3.2 MAIL_PORT

Defines the port used for SMTP connection.

app.config['MAIL_PORT'] = 587
  • 587 → TLS
  • 465 → SSL

13.3.3 MAIL_USE_TLS

Enables TLS (Transport Layer Security).

app.config['MAIL_USE_TLS'] = True
  • Encrypts communication
  • Recommended for security

13.3.4 MAIL_USERNAME

Email account username.

app.config['MAIL_USERNAME'] = 'your_email@gmail.com'

13.3.5 MAIL_PASSWORD

Email account password or app password.

app.config['MAIL_PASSWORD'] = 'your_password'

👉 For Gmail, use App Password, not your real password

🧠 Mail Configuration Flow

13.4 Sending Emails

13.4.1 Mail Instance

Create a Mail object to handle email operations.

from flask_mail import Mail

mail = Mail(app)

13.4.2 Message Object

The Message object defines the email content.

from flask_mail import Message
13.4.2.1 sender

Defines the sender email address.

13.4.2.2 recipients

List of recipient email addresses.

13.4.2.3 body

Content of the email.

Example:

msg = Message(
subject="Hello",
sender="your_email@gmail.com",
recipients=["user@example.com"]
)
msg.body = "This is a test email"

13.4.3 send() Method

Used to send the email.

mail.send(msg)

👉 Sends the email through configured SMTP server

🧠 Complete Example

from flask import Flask
from flask_mail import Mail, Message

app = Flask(__name__)

app.config['MAIL_SERVER'] = 'smtp.gmail.com'
app.config['MAIL_PORT'] = 587
app.config['MAIL_USE_TLS'] = True
app.config['MAIL_USERNAME'] = 'your_email@gmail.com'
app.config['MAIL_PASSWORD'] = 'your_password'

mail = Mail(app)

@app.route('/send')
def send_email():
msg = Message(
subject="Test Email",
sender=app.config['MAIL_USERNAME'],
recipients=["receiver@example.com"]
)
msg.body = "Hello from Flask-Mail"
mail.send(msg)
return "Email Sent"

if __name__ == "__main__":
app.run(debug=True)

🎯 Key Points (Exam Focus)

  • Flask-Mail used to send emails from Flask apps

  • Requires SMTP configuration

  • Important config:

    • MAIL_SERVER
    • MAIL_PORT
    • MAIL_USE_TLS
    • MAIL_USERNAME
    • MAIL_PASSWORD
  • Mail(app) → creates mail instance

  • Message() → defines email

  • mail.send() → sends email

  • Used for:

    • Verification
    • Password reset
    • Notifications

14. Authentication and Authorization (Flask-Login)

14.1 Concepts

14.1.1 Authentication

Authentication is the process of verifying the identity of a user.

  • Confirms who the user is

  • Usually done using:

    • Username & password
    • Email & password

Example:

User enters username and password → system verifies credentials

If valid:

  • User is logged in If invalid:
  • Access is denied

14.1.2 Authorization

Authorization determines what a user is allowed to do after authentication.

  • Controls access to resources
  • Based on roles or permissions

Example:

Admin → can delete users
User → can only view profile

👉 Key difference:

ConceptMeaning
AuthenticationWho are you?
AuthorizationWhat can you do?

14.2 Flask-Login Features

Flask-Login is an extension used to manage user sessions and authentication.

14.2.1 User Session Management

  • Keeps track of logged-in users
  • Stores session data securely
  • Maintains login state across requests

Example:

  • User logs in → session created
  • User stays logged in until logout

14.2.2 User Loader

Flask-Login requires a user loader function.

  • Loads user from database using user ID
  • Required for session management

Example:

from flask_login import LoginManager

login_manager = LoginManager()

@login_manager.user_loader
def load_user(user_id):
return User.get(user_id)

👉 Used internally to:

  • Reload user from session

14.2.3 login_required Decorator

Used to protect routes from unauthorized access.

from flask_login import login_required

@app.route('/dashboard')
@login_required
def dashboard():
return "Protected Page"
  • Only logged-in users can access
  • Others are redirected to login page

14.3 Behavior

14.3.1 Redirect Unauthorized Users to Login Page

If a user tries to access a protected route:

  • Flask-Login automatically:

    • Redirects to login page

Configuration:

login_manager.login_view = 'login'

👉 Ensures:

  • Secure access control
  • Better user experience

🧠 Authentication Flow

14.4 Implementation Steps

14.4.1 Setup Flask App

Install Flask-Login:

pip install flask-login

Import required modules:

from flask import Flask
from flask_login import LoginManager

14.4.2 Initialize LoginManager

app = Flask(__name__)
login_manager = LoginManager()
login_manager.init_app(app)

login_manager.login_view = 'login'

14.4.3 Create User Model

User model must implement required methods:

from flask_login import UserMixin

class User(UserMixin):
def __init__(self, id):
self.id = id

@staticmethod
def get(user_id):
return User(user_id)

👉 UserMixin provides:

  • is_authenticated
  • is_active
  • is_anonymous
  • get_id()

14.4.4 Define Routes (login, logout, protected)

Login Route:

from flask import request
from flask_login import login_user

@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
user = User(request.form['username'])
login_user(user)
return "Logged In"
return "Login Page"

Logout Route:

from flask_login import logout_user

@app.route('/logout')
def logout():
logout_user()
return "Logged Out"

Protected Route:

@app.route('/dashboard')
@login_required
def dashboard():
return "Welcome to Dashboard"

14.4.5 Templates (login.html, home.html)

login.html:

<form method="POST">
<input name="username" placeholder="Enter username">
<input type="submit">
</form>

home.html / dashboard view:

<h1>Welcome User</h1>
<a href="/logout">Logout</a>

🧠 Full Authentication Flow

🎯 Key Points (Exam Focus)

  • Authentication → verify identity
  • Authorization → control access
  • Flask-Login manages user sessions
  • login_required protects routes
  • user_loader loads user from session
  • Unauthorized users → redirected to login
  • login_user() → logs in user
  • logout_user() → logs out user
  • UserMixin provides built-in user methods

15. Deployment of Flask Application

15.1 Introduction

15.1.1 Need for Deployment

Deployment is the process of making a Flask application available to users over the internet.

  • Converts a local app → publicly accessible service
  • Required for real-world usage
  • Allows users to access app via domain/IP

Without deployment:

  • App runs only on local machine
  • Not accessible to others

15.1.2 Production vs Development Server

FeatureDevelopment ServerProduction Server
PurposeTestingReal-world usage
PerformanceLowHigh
SecurityWeakStrong
Exampleapp.run()Gunicorn, Waitress

👉 Important:

  • Flask’s built-in server (app.run()) is NOT suitable for production

15.2 WSGI Servers

WSGI (Web Server Gateway Interface) connects:

  • Web server ↔ Python application

Used for running Flask apps in production.

15.2.1 Gunicorn (Linux)

15.2.1.1 Installation

pip install gunicorn

15.2.1.2 Command Usage

gunicorn -w 4 -b 0.0.0.0:8000 app:app
  • app:app → file name : Flask app instance

15.2.1.3 -w (Workers)

  • Number of worker processes

Example:

-w 4 → 4 worker processes

👉 More workers = better concurrency

15.2.1.4 -b (Bind Address)

  • Defines IP and port

Example:

0.0.0.0:8000
  • 0.0.0.0 → accessible from any IP
  • 8000 → port number

15.2.2 Waitress (Windows)

Used for Windows systems as an alternative to Gunicorn.

Installation:

pip install waitress

Run app:

from waitress import serve
serve(app, host='0.0.0.0', port=8000)

🧠 WSGI Flow

15.3 Reverse Proxy

15.3.1 Purpose (Forward Requests to Flask App)

A reverse proxy sits in front of the Flask app and:

  • Receives client requests
  • Forwards them to Flask server
  • Returns response to client

Benefits:

  • Improved performance
  • Security (hides backend)
  • Load balancing

15.3.2 Nginx Configuration

Nginx is commonly used as a reverse proxy.

Basic steps:

  1. Install Nginx
  2. Configure server block
  3. Forward requests to Flask app

Example config:

server {
listen 80;
location / {
proxy_pass http://127.0.0.1:8000;
}
}

15.3.3 Apache Configuration

Apache can also act as a reverse proxy.

  • Uses modules like:

    • mod_proxy
    • mod_wsgi

Example concept:

ProxyPass / http://127.0.0.1:8000/

🧠 Reverse Proxy Flow

15.4 Deployment Platforms

15.4.1 Heroku

15.4.1.1 Install CLI

Install Heroku CLI:

Download from heroku.com

15.4.1.2 Create Profile

heroku login

15.4.1.3 Deployment Commands

git init
heroku create
git add .
git commit -m "Initial commit"
git push heroku master

👉 Deploys Flask app to cloud

15.4.2 AWS Elastic Beanstalk

  • Cloud platform by AWS

  • Provides pre-configured Python environment

  • Automatically handles:

    • Scaling
    • Load balancing

15.4.3 Docker Deployment

Docker allows containerizing the Flask app.

Example Dockerfile:

FROM python:3.10
WORKDIR /app
COPY . .
RUN pip install -r requirements.txt
CMD ["python", "app.py"]

👉 Benefits:

  • Consistent environment
  • Easy deployment across systems

🧠 Deployment Flow

15.5 Serving Static Files

15.5.1 Static Files in Production

In production:

  • Static files are usually served by:

    • Nginx
    • Apache

👉 Faster than Flask handling them

15.5.2 static Folder Usage

  • Static files stored in static/ folder

  • Includes:

    • CSS
    • JS
    • Images

Example:

static/css/style.css
static/js/script.js

👉 Proper configuration ensures:

  • Faster loading
  • Better performance

🎯 Key Points (Exam Focus)

  • Deployment = making app accessible online

  • app.run() not for production

  • Use WSGI servers:

    • Gunicorn (Linux)
    • Waitress (Windows)
  • Gunicorn flags:

    • -w → workers
    • -b → bind address
  • Reverse proxy:

    • Nginx / Apache
    • Forwards requests to Flask
  • Deployment platforms:

    • Heroku
    • AWS
    • Docker
  • Static files served efficiently in production

16. Summary Concepts (From PDF Table)

16.1 Handling Exceptions

16.1.1 Using @app.errorhandler

Flask provides @app.errorhandler() to handle specific HTTP errors gracefully.

  • Used for errors like:

    • 404 (Not Found)
    • 500 (Internal Server Error)

Example:

@app.errorhandler(404)
def not_found(error):
return "Page Not Found", 404

Key idea:

  • Prevents crash
  • Returns controlled response to user

16.1.2 try-except for Application Errors

Used to handle runtime errors inside application logic.

@app.route('/divide')
def divide():
try:
result = 10 / 0
return str(result)
except Exception:
return "Error occurred"

Key idea:

  • Handles unexpected errors
  • Improves application stability

16.2 Flash Messages

16.2.1 Temporary Notifications

Flash messages are temporary messages stored in session.

  • Displayed once and removed automatically
  • Used for user feedback

Example:

from flask import flash

flash("Login Successful")

16.2.2 Success/Error Display

Flash messages are commonly used for:

  • Success:
"Account created successfully"
  • Error:
"Invalid credentials"

Displayed in templates:

{% for message in get_flashed_messages() %}
<p>{{ message }}</p>
{% endfor %}

16.3 Sending Emails

16.3.1 Flask-Mail Configuration

Flask-Mail requires SMTP configuration:

app.config['MAIL_SERVER'] = 'smtp.gmail.com'
app.config['MAIL_PORT'] = 587
app.config['MAIL_USE_TLS'] = True
app.config['MAIL_USERNAME'] = 'your_email@gmail.com'
app.config['MAIL_PASSWORD'] = 'your_password'

Key idea:

  • Connects Flask app to mail server

16.3.2 Use Cases (Activation, Reset)

Emails are used for:

  • Account activation
  • Password reset
  • Notifications

Example:

"Click here to verify your account"
"Reset your password using this link"

16.4 Deployment

16.4.1 WSGI Servers

Used to run Flask apps in production.

Examples:

  • Gunicorn (Linux)
  • Waitress (Windows)

Key idea:

  • Handles requests efficiently
  • Replaces Flask development server

16.4.2 Reverse Proxy

Acts as an intermediary between client and Flask app.

  • Tools:

    • Nginx
    • Apache

Function:

  • Forwards requests to Flask server
  • Improves performance and security

16.4.3 Cloud Platforms

Flask apps can be deployed on cloud services:

  • Heroku
  • AWS Elastic Beanstalk
  • Docker-based deployments

Key idea:

  • Makes app accessible globally
  • Handles scaling and infrastructure

🎯 Key Points (Exam Focus)

  • @app.errorhandler() handles HTTP errors

  • try-except handles runtime errors

  • Flash messages = temporary notifications

  • Flask-Mail used for sending emails

  • Deployment uses:

    • WSGI servers
    • Reverse proxy
    • Cloud platforms