Introduction to Flask and Its Application Structure
Course: Python Training
Topic: Introduction to Flask and Its Application Structure
Course Link: Python Training Course at JustAcademy
Demo Link: Register for a Course Demo
Website: JustAcademy Official Website
1. Introduction to Flask
Flask is a lightweight web application framework written in Python. It provides tools and features for building websites, web applications, and REST APIs without requiring developers to use a large, predefined application structure.
Flask is commonly described as a microframework because its core focuses on essential web development features such as URL routing, request handling, and response generation. Additional functionality, including database integration, authentication, form validation, and API documentation, can be added using extensions or other Python libraries.
Flask is suitable for beginners learning backend development as well as experienced developers building modular web applications. It works with the Werkzeug WSGI toolkit and uses Jinja as its default template engine.
What Can You Build with Flask?
- Personal websites and blogs.
- Student management and employee management systems.
- REST APIs for web and mobile applications.
- Admin dashboards and reporting applications.
- E-commerce backends and product catalogues.
- Database-driven applications using MySQL, PostgreSQL, or SQLite.
- Machine learning model APIs and data-processing services.
- Authentication systems and user portals.
2. Learning Objectives
After completing this topic, you should be able to:
- Explain Flask and its role in Python web development.
- Understand the request-response cycle.
- Install Flask and create a virtual environment.
- Build and run a basic Flask application.
- Understand routes, view functions, requests, and responses.
- Organize application code into modules and packages.
- Use templates and static files.
- Understand configuration, debugging, and error handling.
- Learn the purpose of Blueprints and application factories.
- Follow good practices when developing and deploying Flask applications.
3. Understanding How Flask Works
A Flask application receives HTTP requests from a client, processes those requests using Python functions, and returns HTTP responses. The client may be a browser, a mobile application, a frontend built with React, or another service communicating with an API.
Request-Response Workflow
- A user opens a URL or submits a form in a browser.
- The browser sends an HTTP request to the Flask application.
- The web server passes the request to the Flask application through the WSGI interface.
- Flask matches the requested URL and HTTP method to a registered route.
- The associated view function executes the application logic.
- The function may access a database, call another service, or render a template.
- Flask creates an HTTP response containing HTML, JSON, text, or another supported response format.
- The browser or client receives and processes the response.
Client or Browser
|
| HTTP Request
v
WSGI Server
|
v
Flask Application
|
v
URL Routing
|
v
View Function
|
+----> Business Logic
|
+----> Database or External API
|
v
HTTP Response
|
v
Client or Browser
4. Important Features of Flask
| Feature |
Description |
Example Use |
| URL Routing |
Maps URLs and HTTP methods to Python functions. |
Displaying a home page. |
| Request Handling |
Provides access to incoming request information. |
Reading form data. |
| Template Rendering |
Uses Jinja to generate dynamic HTML pages. |
Displaying database records. |
| Static Files |
Supports serving CSS, JavaScript, images, and other static assets during development. |
Loading a stylesheet. |
| Sessions and Cookies |
Supports session-based data and cookie handling. |
Maintaining a login session. |
| Error Handling |
Allows custom handlers for HTTP errors and application exceptions. |
Creating a custom 404 page. |
| Extensions |
Add functionality through compatible third-party packages. |
Database integration and form validation. |
| Blueprints |
Organize related routes and functionality into reusable components. |
Separating authentication and products. |
| Testing Support |
Provides a test client for testing application requests. |
Testing a login route. |
5. Installing Python and Flask
Before creating a Flask application, ensure that Python is installed. You can check your Python installation by running the following command in a terminal.
python --version
On some systems, the command may be:
python3 --version
Step 1: Create a Project Directory
mkdir flask_project
cd flask_project
Step 2: Create a Virtual Environment
A virtual environment isolates the dependencies of one Python project from those of other projects.
python -m venv .venv
Activate the environment on Windows:
.venv\Scripts\activate
Activate it on macOS or Linux:
source .venv/bin/activate
Step 3: Install Flask
python -m pip install Flask
Verify the installation:
python -m flask --version
Using a virtual environment and recording project dependencies makes the application easier to reproduce and maintain across different computers.
6. Creating Your First Flask Application
The simplest Flask application can be created in one Python file. Create a file named app.py in your project directory.
from flask import Flask
app = Flask(__name__)
@app.route("/")
def home():
return "Welcome to my first Flask application!"
if __name__ == "__main__":
app.run(debug=True)
Explanation of the Code
from flask import Flask imports the Flask class.
app = Flask(__name__) creates the Flask application instance.
@app.route("/") registers a route for the root URL.
def home(): defines the view function associated with that route.
return provides the response body sent to the client.
if __name__ == "__main__": ensures the development server starts when the file is executed directly.
debug=True enables development debugging and automatic reloading when supported.
The __name__ value helps Flask determine where to locate resources such as templates and static files.
7. Running the Flask Application
Open a terminal in the project directory and run:
python -m flask --app app run --debug
Flask starts a local development server. Open the address displayed in the terminal, commonly http://127.0.0.1:5000/, in your browser.
You should see the message:
Welcome to my first Flask application!
You can also use the following command for a simple application when you have included the development-server block in app.py:
python app.py
Important: Debug mode is intended for local development. Never enable Flask's interactive debugger on a publicly accessible production server because it can expose sensitive information and potentially allow code execution.
8. Understanding the Flask Application Object
The Flask application object is the central object that manages application configuration, routes, registered Blueprints, extensions, and other application-level behavior.
from flask import Flask
app = Flask(__name__)
@app.route("/")
def index():
return "Home Page"
@app.route("/about")
def about():
return "About Page"
In this example, one application object manages two routes. As the project grows, route definitions and related functionality can be moved into separate modules or Blueprints.
9. Understanding URL Routing
Routing connects a URL pattern to a Python view function. Flask uses the registered routes to determine which function should process a request.
9.1 Static Routes
@app.route("/contact")
def contact():
return "Contact Us"
When a client requests /contact using the GET method, Flask calls the contact() function.
9.2 Dynamic Routes
Dynamic routes allow part of the URL to be passed to the view function.
@app.route("/user/<username>")
def user_profile(username):
return f"Welcome, {username}!"
For example, requesting /user/rahul passes the string rahul to the function.
9.3 Routes with Integer Parameters
@app.route("/product/<int:product_id>")
def product_details(product_id):
return f"Product ID: {product_id}"
The int converter ensures that the route parameter is interpreted as an integer. Flask supports other route converters, including string, path, float, and UUID.
9.4 Using URL Generation
The url_for() function generates URLs based on registered endpoint names. It reduces the need to hard-code URL paths throughout an application.
from flask import Flask, url_for
app = Flask(__name__)
@app.route("/")
def home():
return "Home"
@app.route("/profile/<username>")
def profile(username):
return f"Profile: {username}"
with app.test_request_context():
print(url_for("home"))
print(url_for("profile", username="rahul"))
10. Understanding HTTP Methods
HTTP methods describe the type of operation a client wants to perform. Flask routes can support one or more methods.
| Method |
Common Purpose |
Example |
| GET |
Retrieve a resource. |
Display a product. |
| POST |
Submit data or request creation of a resource. |
Register a user. |
| PUT |
Replace a resource representation. |
Replace product details. |
| PATCH |
Partially update a resource. |
Change a product price. |
| DELETE |
Request removal of a resource. |
Delete a record. |
Example of handling GET and POST requests:
from flask import Flask, request
app = Flask(__name__)
@app.route("/submit", methods=["GET", "POST"])
def submit():
if request.method == "POST":
username = request.form.get("username", "").strip()
if not username:
return "Username is required", 400
return f"Submitted: {username}"
return """
<form method="post">
<input name="username" placeholder="Enter username">
<button type="submit">Submit</button>
</form>
"""
For production applications, render forms using templates and add appropriate validation and CSRF protection when handling state-changing browser requests.
11. Understanding Request and Response Objects
Flask provides a request object that contains information about an incoming HTTP request. Depending on the request, the application may access query parameters, form values, JSON payloads, request headers, and uploaded files.
Reading Query Parameters
from flask import Flask, request
app = Flask(__name__)
@app.route("/search")
def search():
keyword = request.args.get("q", "")
return f"Search keyword: {keyword}"
A URL such as /search?q=python supplies python as the search keyword.
Reading JSON Data
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route("/api/message", methods=["POST"])
def receive_message():
data = request.get_json(silent=True) or {}
message = data.get("message", "")
if not isinstance(message, str) or not message.strip():
return jsonify({"error": "A message is required"}), 400
return jsonify({
"status": "success",
"message": message
}), 200
The jsonify() function creates a JSON response. Validate the expected structure and data types of incoming JSON before using the values in business logic or database queries.
12. Understanding Templates in Flask
Templates allow developers to generate dynamic HTML pages. Flask uses the Jinja template engine by default and searches for HTML templates in a directory named templates.
Project Structure
flask_project/
app.py
templates/
index.html
Python File: app.py
from flask import Flask, render_template
app = Flask(__name__)
@app.route("/")
def home():
return render_template(
"index.html",
title="Flask Learning",
username="Aarav"
)
HTML File: templates/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{ title }}</title>
</head>
<body>
<h1>Welcome, {{ username }}!</h1>
<p>This page is rendered using a Flask template.</p>
</body>
</html>
Flask passes the supplied values to the template, where Jinja substitutes them into the HTML. For ordinary HTML templates, Jinja enables autoescaping by default, helping prevent untrusted values from being interpreted as HTML markup.
13. Understanding Static Files
Static files include CSS stylesheets, JavaScript files, images, fonts, and other assets that do not need to be generated dynamically for each request.
Recommended Structure
flask_project/
app.py
templates/
index.html
static/
css/
style.css
js/
app.js
images/
logo.png
Reference static files in a template with url_for():
<link rel="stylesheet"
href="{{ url_for('static', filename='css/style.css') }}">
<script src="{{ url_for('static', filename='js/app.js') }}"></script>
Using url_for('static', ...) helps generate the correct URL without hard-coding the static path.
14. Understanding Flask Application Structure
A small Flask application can be implemented in a single file. However, as more features are added, separating routes, business logic, templates, configuration, and database access makes the project easier to understand and maintain.
14.1 Basic Structure for Beginners
flask_project/
app.py
templates/
index.html
about.html
static/
css/
style.css
images/
logo.png
This structure is appropriate for learning Flask and building small applications with only a few routes.
14.2 Modular Application Structure
flask_project/
app/
__init__.py
routes.py
models.py
services.py
templates/
base.html
index.html
static/
css/
style.css
tests/
test_routes.py
config.py
requirements.txt
run.py
This structure separates application initialization, routes, models, services, tests, configuration, and dependencies. It is a useful starting point for a medium-sized application, although the precise layout should match the project's needs.
14.3 Explanation of Important Files and Directories
| File or Directory |
Purpose |
app/ |
Contains the main application package. |
__init__.py |
Initializes the package and may define the application factory. |
routes.py |
Defines URL routes and request handlers. |
models.py |
Defines data models or database-related structures. |
services.py |
Contains reusable business logic. |
templates/ |
Stores Jinja HTML templates. |
static/ |
Stores CSS, JavaScript, images, and other static assets. |
tests/ |
Contains automated tests. |
config.py |
Stores configuration classes or settings-loading logic. |
requirements.txt |
Lists Python package dependencies. |
run.py |
May provide a convenient local entry point for running the app. |
15. Creating a Flask Application with an Application Factory
An application factory is a function that creates and configures a Flask application. This approach supports multiple configurations, simplifies testing, and works well with Blueprints and extensions.
File: app/__init__.py
from flask import Flask
def create_app():
app = Flask(__name__)
app.config["SECRET_KEY"] = "replace-this-development-key"
from .routes import main
app.register_blueprint(main)
return app
File: app/routes.py
from flask import Blueprint
main = Blueprint("main", __name__)
@main.route("/")
def home():
return "Welcome to the Flask application factory!"
Run the Application
python -m flask --app app:create_app run --debug
The command tells Flask to import the app package and call its create_app() function. In a real application, load the secret key from a secure configuration source rather than hard-coding it.
16. Understanding Blueprints
Blueprints allow related routes, templates, static resources, and other application functionality to be organized into separate components. They are useful when a project has multiple feature areas, such as authentication, products, orders, and administration.
Example: Product Blueprint
from flask import Blueprint, jsonify
products = Blueprint("products", __name__, url_prefix="/products")
@products.route("/")
def list_products():
return jsonify([
{"id": 1, "name": "Keyboard"},
{"id": 2, "name": "Mouse"}
])
Register the Blueprint in the application factory:
from flask import Flask
from .products import products
def create_app():
app = Flask(__name__)
app.register_blueprint(products)
return app
After registration, the route is available at /products/. Blueprints do not create independent applications; they provide a way to organize components that are registered with a Flask application.
17. Configuration Management
Configuration settings control how the application behaves in different environments. Typical settings include secret keys, database connection information, testing options, and feature flags.
Example Configuration
import os
class Config:
SECRET_KEY = os.environ.get("SECRET_KEY")
TESTING = False
class DevelopmentConfig(Config):
DEBUG = True
class ProductionConfig(Config):
DEBUG = False
Load the appropriate configuration when creating the application:
from flask import Flask
from config import DevelopmentConfig
def create_app():
app = Flask(__name__)
app.config.from_object(DevelopmentConfig)
return app
For production, supply a strong secret key through a secure environment variable or secrets manager. Do not use a development secret key or expose credentials in source control.
18. Handling Errors in Flask
Web applications should handle errors consistently and return suitable HTTP status codes. Flask supports custom error handlers for common HTTP errors and application exceptions.
Custom 404 Page
from flask import Flask, render_template
app = Flask(__name__)
@app.errorhandler(404)
def page_not_found(error):
return render_template("404.html"), 404
Create templates/404.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Page Not Found</title>
</head>
<body>
<h1>404 - Page Not Found</h1>
<p>The requested page could not be found.</p>
<a href="/">Return to Home</a>
</body>
</html>
During development, inspect error logs to identify the cause of a problem. In production, show user-friendly error pages and avoid exposing stack traces or sensitive internal details.
19. Integrating Flask with a Database
Many Flask applications need persistent data storage. Flask itself does not force the use of a particular database system. Developers can integrate relational databases such as MySQL or PostgreSQL, or use SQLite for small applications and prototypes.
Common approaches include:
- Direct database connector: Execute SQL using a driver such as MySQL Connector/Python.
- Object-relational mapper: Use a library such as Flask-SQLAlchemy to map database tables to Python objects.
- Repository pattern: Separate database queries from routes and business logic.
Example route using a service function:
from flask import Flask, jsonify
app = Flask(__name__)
def get_products():
# Replace this example data with a database query.
return [
{"id": 1, "name": "Laptop"},
{"id": 2, "name": "Monitor"}
]
@app.route("/api/products")
def products_api():
return jsonify(get_products())
This example returns sample data. In a real application, the service function would retrieve records from the configured database and handle database errors appropriately.
20. Flask for REST API Development
Flask can be used to build REST APIs that exchange data, usually in JSON format, with frontend applications, mobile applications, and other services.
Example JSON Endpoint
from flask import Flask, jsonify
app = Flask(__name__)
@app.get("/api/status")
def status():
return jsonify({
"application": "Flask Demo",
"status": "running"
}), 200
When the client requests /api/status, the application returns JSON and a successful HTTP status code. A production API should also consider input validation, authentication, authorization, rate limiting, logging, versioning, and consistent error responses.
21. Testing a Flask Application
Automated tests help verify that routes return the expected responses. Flask provides a test client that can make requests to an application without starting a live network server.
Example Test
import unittest
from app import app
class FlaskAppTests(unittest.TestCase):
def setUp(self):
app.config["TESTING"] = True
self.client = app.test_client()
def test_home_page(self):
response = self.client.get("/")
self.assertEqual(response.status_code, 200)
self.assertIn(b"Welcome", response.data)
if __name__ == "__main__":
unittest.main()
This test assumes the application is defined in app.py and its home route returns a response containing the word Welcome. Adapt the test to match the actual route and response in your project.
22. Common Flask Errors and Troubleshooting
| Problem |
Possible Cause |
Solution |
ModuleNotFoundError: No module named 'flask' |
Flask is not installed in the active Python environment. |
Activate the correct virtual environment and install Flask. |
Address already in use |
Another process is using the selected port. |
Stop the other development server or select an available port. |
| 404 Not Found |
The requested URL does not match a registered route. |
Check the route path, trailing slash, and URL. |
| 405 Method Not Allowed |
The route does not support the HTTP method used. |
Register the required method or send the correct request. |
| TemplateNotFound |
The template is missing or placed in the wrong directory. |
Verify the name and location under the application's templates directory. |
| Static file not loading |
The file path is incorrect. |
Check the static directory and use url_for('static', filename='...'). |
| Import errors |
Incorrect package structure or circular imports. |
Review imports and organize initialization carefully. |
| Changes are not reflected |
The development server may not have reloaded, or a cached asset may be used. |
Check the server output and browser cache. |
| Application fails in production |
Missing environment variables or incorrect deployment configuration. |
Review logs, configuration, dependencies, and production server settings. |
23. Flask Development Best Practices
- Use a virtual environment for each project.
- Keep dependencies recorded in
requirements.txt or another appropriate dependency file.
- Separate routes, services, database access, and templates as the application grows.
- Use Blueprints to organize independent application features.
- Use application factories when multiple configurations or testing environments are needed.
- Use Jinja templates for HTML instead of concatenating user input into HTML strings.
- Validate request data and use parameterized SQL queries for database operations.
- Store secret keys, passwords, and API credentials securely.
- Use suitable error handlers and logging.
- Write automated tests for routes, business logic, and database operations.
- Disable debug mode in production.
- Use a production-ready WSGI server and follow the deployment guidance for your hosting environment.
24. Mini Project: Student Information Web Application
Project Objective: Build a simple Flask web application that displays student information and provides a foundation for CRUD operations.
Project Features
- Display a home page with application information.
- Show a list of students.
- Display an individual student's details.
- Add student records through a form.
- Update existing student details.
- Delete records after confirmation.
- Validate form input and handle invalid requests.
- Store student data in a database.
- Use reusable templates and static CSS files.
- Write tests for the main routes.
Suggested Project Structure
student_app/
app/
__init__.py
routes.py
services.py
models.py
templates/
base.html
index.html
students.html
student_detail.html
static/
css/
style.css
tests/
test_routes.py
config.py
requirements.txt
Development Steps
- Create the project directory and virtual environment.
- Install Flask and the required database package.
- Create the Flask application and configure the routes.
- Create the base HTML template and page-specific templates.
- Implement the student data model and database operations.
- Build forms for adding and editing records.
- Validate input and display suitable error messages.
- Organize student routes using a Blueprint.
- Write tests for successful and unsuccessful requests.
- Document how to install, configure, run, and test the application.
25. Practical Exercises
- Create a Flask application that displays a welcome message on the home page.
- Add routes for Home, About, Contact, and Services.
- Create a dynamic route that accepts a username and displays a greeting.
- Build a route that accepts a product ID as an integer.
- Create an HTML template that displays values passed from Python.
- Add a CSS file in the static directory and load it in a template.
- Build a form that accepts a user's name and email address.
- Create a JSON API endpoint that returns a list of products.
- Implement a custom 404 error page.
- Organize routes into a Blueprint.
- Create an application factory and load configuration settings.
- Write an automated test for the home page.
- Build a simple student information application connected to a database.
26. Interview Questions and Answers
Q1. What is Flask?
Answer: Flask is a lightweight Python web framework used to build websites, web applications, and APIs. It provides routing, request handling, and response generation, with additional features available through extensions.
Q2. Why is Flask called a microframework?
Answer: Flask has a relatively small core and does not require a particular project structure or built-in solution for every application feature. Developers can add the libraries and patterns that suit their project.
Q3. What does Flask(__name__) do?
Answer: It creates a Flask application instance. The module name helps Flask locate resources and determine the application's import context.
Q4. What is a route in Flask?
Answer: A route maps a URL pattern and supported HTTP methods to a view function.
Q5. What is a view function?
Answer: A view function processes a matched request and returns a response, such as HTML, plain text, JSON, or a redirect.
Q6. What is Jinja?
Answer: Jinja is a template engine used by Flask to generate dynamic content, including HTML pages, using variables, expressions, conditions, loops, and template inheritance.
Q7. What is the purpose of the templates directory?
Answer: It stores template files, typically HTML files, that Flask renders using Jinja.
Q8. What is the purpose of the static directory?
Answer: It stores static assets such as CSS, JavaScript, images, and fonts.
Q9. What is a Blueprint?
Answer: A Blueprint groups related routes and other application resources into a component that can be registered with a Flask application.
Q10. What is an application factory?
Answer: It is a function, often named create_app(), that creates and configures a Flask application instance.
Q11. What is the difference between GET and POST?
Answer: GET is commonly used to retrieve resources, while POST is commonly used to submit data or request creation of a resource. The appropriate method depends on the operation's semantics.
Q12. What does url_for() do?
Answer: It generates a URL from a registered endpoint name and optional route parameters, reducing hard-coded URL paths.
Q13. What is the Flask development server?
Answer: It is a server intended for local development and testing. Production deployments should use a suitable production WSGI server or hosting platform.
Q14. Why should debug mode be disabled in production?
Answer: Debug mode may expose sensitive information and its interactive debugger can create severe security risks if accessible to untrusted users.
Q15. How can Flask connect to a database?
Answer: Flask can use database drivers, ORMs, or compatible extensions to communicate with databases such as MySQL, PostgreSQL, and SQLite.
27. Quick Revision Checklist
- Flask is a lightweight Python web framework.
- The Flask application object manages routes, configuration, and registered components.
- Routes connect URLs to view functions.
- HTTP methods define the intended type of request.
- The request object provides access to incoming request data.
- Templates and Jinja support dynamic HTML generation.
- The static directory contains CSS, JavaScript, and images.
- Application packages help organize code into reusable modules.
- Blueprints group related features and routes.
- Application factories simplify initialization and testing.
- Error handlers provide consistent error responses.
- Configuration and secrets should be managed securely.
- Automated tests help verify routes and application behavior.
- Debug mode is for development, not production.
28. Conclusion
Flask provides a flexible starting point for Python web development. Understanding the application object, URL routing, request-response workflow, templates, static files, and project structure makes it easier to create applications that are organized and maintainable.
As projects grow, developers can use Blueprints, application factories, configuration management, database integration, and automated testing to build more robust applications. Practising these concepts through a student management system or REST API will help strengthen your backend development skills.
Learn more through the Python Training Course at JustAcademy, register through the course demo registration page, or visit the JustAcademy official website.
29. Additional Learning Resource
For further technical reference, consult the official Flask Quickstart documentation and the official Flask tutorial.