Logo OnlineCBT
PYTHON Tutorial
PYTHON · LESSON 57

Web Development with Flask

Build a small server-rendered web application.

Level: Beginner to Advanced
Duration: ~60 Mins Deep-Dive
Updated: 26 Jul 2026

Lesson 57: Web Development with Flask

1. Introduction to Web Application Engineering & WSGI Architecture

Welcome to Module 10 of our Python Mastery Series: Web Application Development and Web Frameworks! Up to this point, our Python programs interacted with external services by acting as HTTP clients (via requests in Lesson 54) or parsing local file stores and databases (SQLite in Lesson 53).

In this module, we step onto the server side of web architecture: constructing production-grade HTTP web servers, RESTful microservices, and dynamic web portals. When a client browser or mobile application submits an HTTP request over the network to a web domain, an enterprise web application server must receive the incoming HTTP connection, parse URI routes, execute business logic, query databases, and return structured HTML or JSON HTTP responses.

In Python web development, the standard communication bridge between underlying Web Servers (like Gunicorn, Nginx, or uWSGI) and Python web application frameworks is WSGI (Web Server Gateway Interface - PEP 3333).

To build server-side applications without writing low-level network socket logic, developers use web frameworks. The premier lightweight, flexible WSGI micro-framework in Python is Flask.

In this lesson, we will master the fundamentals of Flask, construct application instances and routes using @app.route(), handle dynamic URL parameters and type converters, parse incoming request data (`request.args`, `request.get_json()`), return JSON web API responses via jsonify(), render dynamic HTML user interfaces using the Jinja2 Templating Engine, and route HTTP request events using Structural Pattern Matching (`match-case`).


2. Flask Micro-framework Mechanics & Routing Architecture

Flask is categorized as a micro-framework because it provides core web routing, request handling, and template rendering without imposing rigid, monolithic database or ORM structures. This gives developers complete architectural freedom.

# Installing Flask micro-framework:
pip install flask
    

1. Application Instance and Route Declarations

Every Flask application begins by instantiating the Flask(__name__) object class. Web routes are registered using the decorator syntax `@app.route("/path")`, binding specific URL paths directly to Python view functions.

2. Dynamic URL Converters Table

  • string (Default)
  • Any text string without slashes
  • /user/alice
  • def user_profile(username: str)
  • int
  • Positive Integers strictly
  • /orders/1001
  • def get_order(order_id: int)
  • float
  • Floating-point numbers
  • /rates/83.50
  • def convert_currency(rate: float)
  • path
  • Strings including forward slashes
  • /files/docs/2026/report.pdf
  • def fetch_file(filepath: str)
  • uuid
  • Standard UUID strings
  • /item/123e4567-e89b...
  • def fetch_item(item_uuid: UUID)
URL Converter Specifier Matched Data Type Example URL Pattern View Function Variable Signature
FLASK_BASIC_ROUTING.PY
from flask import Flask, jsonify, request

# 1. Instantiating the core Flask application object
app = Flask(__name__)

# 2. Registering a Static Root Route
@app.route("/", methods=["GET"])
def home_index():
    """Root endpoint returning system greeting."""
    return jsonify({
        "status": "ONLINE",
        "system": "Enterprise Flask Gateway v1.0",
        "timestamp": "2026-07-26 22:15:00 UTC"
    }), 200

# 3. Registering Dynamic Route with URL Type Converters
@app.route("/api/v1/accounts/", methods=["GET"])
def fetch_account_details(account_id: int):
    """
    Dynamic endpoint demonstrating 'int' type converter.
    Matches URIs like /api/v1/accounts/1001 cleanly!
    """
    # Simulated database lookup
    if account_id == 1001:
        return jsonify({
            "account_id": account_id,
            "owner": "Alice Developer",
            "balance": 12500.50,
            "status": "ACTIVE"
        }), 200
    
    return jsonify({"error": f"Account #{account_id} not found!"}), 404

print("=== Flask Application Routes Registered Cleanly ===")
for rule in app.url_map.iter_rules():
    print(f"Path: {rule.rule:<30} | Methods: {', '.join(rule.methods)}")
OUTPUT
=== Flask Application Routes Registered Cleanly ===
Path: /                              | Methods: GET, HEAD, OPTIONS
Path: /api/v1/accounts/ | Methods: GET, HEAD, OPTIONS
Path: /static/       | Methods: GET, HEAD, OPTIONS

3. Request Handling & JSON API Payload Processing

When clients interact with a Flask web application, Flask provides the global thread-safe `flask.request` object to access incoming HTTP metadata:

  • request.method: Returns the active HTTP method verb (e.g., "GET", "POST").
  • request.args: A dictionary-like object containing URL query parameters (e.g., ?search=python&limit=10).
  • request.get_json(): Parses incoming HTTP Request Body JSON payloads directly into Python dictionary objects.
  • request.form: Accesses submitted HTML form field key-value inputs.
HTTP Status Code Tuples in Flask: Flask view functions return response tuples: return payload, status_code (e.g., return jsonify(data), 201). If the status code integer is omitted, Flask defaults to 200 OK automatically.
FLASK_REQUEST_PAYLOAD_DEMO.PY
from flask import Flask, jsonify, request

app = Flask(__name__)

# Endpoint demonstrating handling Query Parameters and POST JSON Payloads
@app.route("/api/v1/transactions", methods=["GET", "POST"])
def manage_transactions():
    if request.method == "GET":
        # Extracting URL Query parameters: /api/v1/transactions?limit=2&status=ACTIVE
        limit = request.args.get("limit", default=10, type=int)
        status_filter = request.args.get("status", default="ALL", type=str)
        
        return jsonify({
            "operation": "QUERY_TRANSACTIONS",
            "applied_limit": limit,
            "applied_filter": status_filter,
            "records_returned": 2
        }), 200

    elif request.method == "POST":
        # Parsing JSON body payload from client request
        payload = request.get_json(silent=True)
        if not payload or "account_id" not in payload or "amount" not in payload:
            return jsonify({
                "error": "BAD_REQUEST",
                "message": "JSON body payload must contain 'account_id' and 'amount'!"
            }), 400
        
        account_id = payload.get("account_id")
        amount = float(payload.get("amount"))
        
        return jsonify({
            "status": "TRANSACTION_PROCESSED",
            "transaction_id": "TX_99018",
            "account_id": account_id,
            "processed_amount": amount
        }), 201

# Testing Request Logic via Flask's Built-In Test Client (No live server required for tests!)
with app.test_client() as client:
    print("=== 1. Testing GET Request with Query Args ===")
    get_res = client.get("/api/v1/transactions?limit=2&status=ACTIVE")
    print("Status Code :", get_res.status_code)
    print("JSON Output :", get_res.get_json())

    print("\n=== 2. Testing POST Request with Valid JSON Body ===")
    post_res = client.post(
        "/api/v1/transactions",
        json={"account_id": "ACC_1001", "amount": 450.00}
    )
    print("Status Code :", post_res.status_code)
    print("JSON Output :", post_res.get_json())
OUTPUT
=== 1. Testing GET Request with Query Args ===
Status Code : 200
JSON Output : {'applied_filter': 'ACTIVE', 'applied_limit': 2, 'operation': 'QUERY_TRANSACTIONS', 'records_returned': 2}

=== 2. Testing POST Request with Valid JSON Body ===
Status Code : 201
JSON Output : {'account_id': 'ACC_1001', 'processed_amount': 450.0, 'status': 'TRANSACTION_PROCESSED', 'transaction_id': 'TX_99018'}

4. Dynamic HTML Templating via Jinja2

While web APIs return JSON data, full-stack web applications render dynamic user interfaces using HTML templates. Flask integrates the Jinja2 Templating Engine, allowing developers to inject Python variables, iterate over loops, and evaluate conditional logic directly inside HTML template files using render_template()!

1. Essential Jinja2 Delimiter Syntax

  • {{ variable }}
  • Variable Interpolation
  • Welcome, {{ user.name }}!

  • {% statement %}
  • Control Logic Statement
  • {% for item in items %} ... {% endfor %}
  • {# comment #}
  • Template Comment
  • {# This comment is omitted from HTML output #}
Jinja2 Delimiter Syntax Template Expression Type Usage Example inside HTML
JINJA2_TEMPLATE_RENDER_DEMO.PY
from flask import Flask, render_template_string

app = Flask(__name__)

# Sample Jinja2 HTML Template String (Demonstrating conditionals and loop tags)
JINJA_HTML_TEMPLATE = """


{{ page_title }}

    

System Audit Portal — {{ page_title }}

User Role: {{ current_role }}

{% if is_admin %}

SECURITY: Administrator privileges verified.

{% else %}

SECURITY: Standard restricted view mode.

{% endif %}

Active Operational Log Records:

    {% for log in log_entries %}
  • [{{ log.level }}] {{ log.timestamp }}: {{ log.message }}
  • {% endfor %}
""" @app.route("/dashboard") def view_dashboard(): """Renders Jinja2 HTML template with dynamic Python variables.""" logs = [ {"level": "INFO", "timestamp": "22:15:00", "message": "Auth cluster online"}, {"level": "WARN", "timestamp": "22:15:02", "message": "Database query latency 120ms"} ] return render_template_string( JINJA_HTML_TEMPLATE, page_title="Executive Dashboard", current_role="ADMIN", is_admin=True, log_entries=logs ) with app.test_client() as client: res = client.get("/dashboard") print("=== Jinja2 Rendered HTML Output Inspection ===") # Printing rendered HTML text print(res.get_data(as_text=True).strip()[:400] + "\n...")
OUTPUT
=== Jinja2 Rendered HTML Output Inspection ===


Executive Dashboard

    

System Audit Portal — Executive Dashboard

User Role: ADMIN

SECURITY: Administrator privileges verified.

Active Operational Log Records:

  • [INFO] 22:15:00: Auth cluster online
  • ...

5. Combining Flask Web Requests with `match-case` Pattern Matching

Building web API gateway dispatchers involves receiving incoming request payloads or routing HTTP event tokens, passing dictionary data or request tuples directly into Python 3.10+ `match-case` Structural Pattern Matching engines.

MATCH_CASE_FLASK_DISPATCHER.PY
from flask import Flask, jsonify, request

app = Flask(__name__)

def evaluate_web_route_payload(route_tuple: tuple) -> tuple[dict, int]:
    """
    Routes HTTP method and path pattern tuples using Structural Pattern Matching.
    Demonstrates evaluating web service routing logic dynamically.
    """
    match route_tuple:
        case ("GET", "/api/v1/health"):
            return {"status": "HEALTHY", "uptime": "99.99%"}, 200

        case ("POST", "/api/v1/vault", {"action": "LOCK", "user": str(u)}):
            return {"status": "VAULT_LOCKED", "operator": u}, 200

        case ("POST", "/api/v1/vault", {"action": "UNLOCK", "user": str(u), "key": str(k)}) if len(k) >= 16:
            return {"status": "VAULT_UNLOCKED", "operator": u}, 200

        case ("POST", "/api/v1/vault", _):
            return {"error": "INVALID_VAULT_PAYLOAD", "message": "Key criteria or action missing!"}, 400

        case (str(method), str(path), _):
            return {"error": "ROUTE_NOT_FOUND", "path": path, "method": method}, 404

        case _:
            return {"error": "BAD_REQUEST_SCHEMA"}, 400

# Testing Dispatcher Logic
print("=== Pattern Matched Web Route Dispatcher Outputs ===")
print("1. Health Endpoint :", evaluate_web_route_payload(("GET", "/api/v1/health")))
print("2. Lock Endpoint   :", evaluate_web_route_payload(("POST", "/api/v1/vault", {"action": "LOCK", "user": "alice_admin"})))
print("3. Invalid Key     :", evaluate_web_route_payload(("POST", "/api/v1/vault", {"action": "UNLOCK", "user": "bob", "key": "short_key"})))
print("4. Unknown Route   :", evaluate_web_route_payload(("DELETE", "/api/v1/legacy", None)))
OUTPUT
=== Pattern Matched Web Route Dispatcher Outputs ===
1. Health Endpoint : ({'status': 'HEALTHY', 'uptime': '99.99%'}, 200)
2. Lock Endpoint   : ({'status': 'VAULT_LOCKED', 'operator': 'alice_admin'}, 200)
3. Invalid Key     : ({'error': 'INVALID_VAULT_PAYLOAD', 'message': 'Key criteria or action missing!'}, 400)
4. Unknown Route   : ({'error': 'ROUTE_NOT_FOUND', 'method': 'DELETE', 'path': '/api/v1/legacy'}, 404)

6. Frequently Asked Interview Questions with Answers

Q1: What is WSGI (PEP 3333), and why is it important in Python web development?
Answer: WSGI (Web Server Gateway Interface) is the standardized specification defining how production web servers (such as Nginx, Gunicorn, or uWSGI) communicate with Python web application frameworks (such as Flask or Django). WSGI decouples web servers from web frameworks, allowing any WSGI-compliant application to run on any WSGI web server seamlessly.
Q2: Why is Flask described as a "Micro-framework"?
Answer: Flask is called a micro-framework because its core is lightweight—providing basic routing, request handling, and Jinja2 templating—without bundling complex default dependencies like ORMs, database abstraction layers, or form validation engines. Developers add third-party extensions as needed.
Q3: How do dynamic URL converters work in Flask routes (e.g., `@app.route('/user/')`)?
Answer: URL converters match specific data types directly inside the URI path. Flask automatically casts matched URL path parameters to specified Python types (e.g., converting "1001" to integer 1001) and passes them as typed arguments into the decorated view function, returning a 404 Not Found automatically if type constraints fail!
Q4: How does `request.args` differ from `request.get_json()` in Flask?
Answer: request.args parses URL Query Parameters (e.g., ?page=1&limit=10) passed in the URI line of GET requests. request.get_json() parses JSON-encoded payload strings transmitted in the HTTP Request Body of POST/PUT requests into Python dictionaries.
Q5: What is Jinja2, and how do delimiters like `{{ ... }}` and `{% ... %}` function?
Answer: Jinja2 is Flask's dynamic HTML template engine. The double curly brace syntax {{ variable }} interpolates Python variable values into the HTML output stream. The percent syntax {% statement %} executes control flow logic (such as for loops and if-else conditionals) inside template files.

7. Homework & Practical Assignments

Task 1: Multi-Route Flask Microservice API

Create a script named flask_api_task.py inside your lesson_57 folder:

  • Instantiate a Flask app and register three routes:
    • GET /api/status → Returns {"status": "RUNNING", "version": "1.0.0"} with status code 200.
    • GET /api/users/ → Returns user JSON dictionary if uid > 0 else 404 error.
    • POST /api/echo → Parses incoming JSON body and echoes it back with status code 201.
  • Test all three endpoints using app.test_client() and print status codes and JSON outputs using f-strings.

Task 2: Pattern-Matched Web Route Request Dispatcher

Create a script named flask_dispatcher_task.py:

  • Build function route_request_event(method: str, path: str, payload: dict | None = None) -> str.
  • Write a match-case dispatcher:
    • case ("GET", "/health", _) → Return "200_HEALTH_OK".
    • case ("POST", "/login", {"user": str(u), "pass": str(p)}) if len(p) >= 8 → Return "200_AUTH_SUCCESS".
    • case ("POST", "/login", _) → Return "400_WEAK_PASSWORD".
    • case _ → Return "404_ROUTE_MISSING".
  • Execute test calls across 4 route combinations and print output result strings.

Task 3: Master Review Capstone Project — Production Enterprise Web Service & API Gateway OS (`web_service_os.py`)

Create a script named web_service_os.py inside your lesson_57 folder. This assignment tests and integrates **ALL concepts learned across Lessons 1 through 57**.

Project Architectural Requirements Specification:

  1. Flask Web Development Architecture (Lesson 57):
    • Construct a modular Flask application with dynamic URL converters, request JSON parsing (`request.get_json()`), query arguments (`request.args`), and Jinja2 HTML template rendering (`render_template_string`).
    • Verify application routes using Flask's built-in test_client() context manager.
  2. RPA & Office Automation Integration (Lesson 56):
    • Generate Excel summary reports via openpyxl and export email payload alerts using email.message.EmailMessage when specific Flask routes are invoked.
  3. Web Scraping Integration (Lesson 55):
    • Extract HTML DOM elements using BeautifulSoup4 (`bs4`) to serve populated dashboard views inside Flask routes.
  4. HTTP APIs & requests Integration (Lesson 54):
    • Integrate background HTTP external health checks via requests.Session().
  5. SQLite Persistence Integration (Lesson 53):
    • Persist Web API request log records into an SQLite database table using parameterized SQL statements and sqlite3.Row.
  6. Security, Performance & Memory Hardening (Lesson 52):
    • Use __slots__ across core domain models for memory optimization.
    • Read web secret keys and port configurations from environment variables using os.environ.
  7. Packaging & Distribution Integration (Lesson 51):
    • Include a programmatically generated pyproject.toml package specification string and an argparse CLI entry point structure.
  8. Clean Code, Documentation & Refactoring (Lesson 50):
    • Apply SOLID principles, DRY, and Google Style Docstrings across all functions and classes.
  9. Testing & Quality Assurance (Lessons 47-48):
    • Include unit tests verified via pytest fixtures testing Flask routes.
  10. Asyncio & Concurrency Integration (Lessons 45-46):
    • Incorporate thread pool workers or async event loops for background task execution.
  11. Temporal & RegEx Text Processing (Lessons 43-44):
    • Parse UTC-aware timestamps using datetime and zoneinfo.ZoneInfo.
    • Pre-compile RegEx patterns with Named Groups for parsing HTTP URI paths.
  12. Type Hints, Generics & Static Safety (Lesson 42):
    • Apply explicit modern type annotations (X | Y, list[str], dict[str, Any]) throughout all functions and classes.
  13. Metaprogramming, Closures & Decorators (Lessons 40-41):
    • Build function factories and 3-level configurable decorators with @functools.wraps.
  14. Iterators & Generators (Lesson 39):
    • Implement generator functions streaming web log cursor rows lazily with $O(1)$ memory.
  15. Full OOP Architecture (Lessons 32-38):
    • Define abstract base class BaseWebService(ABC) and concrete Data Classes WebRouteRecord and APIAuditEntry.
    • Build composite manager WebServiceOS composing database persistence drivers and web server context handles.
  16. Observability & Fault Tolerance (Lessons 29-31):
    • Set up multi-handler logging to console and web_service.log file.
    • Incorporate developer assertions (assert) verifying route response bounds.
    • Define custom exception hierarchy (WebServiceOSError, RouteNotFoundError).
  17. Context Managers & Persistence Layer (Lessons 27-30):
    • Use custom class-based context managers to manage test client handles.
    • Persist JSON payload backups to web_db.json and export CSV reports to route_audit.csv using pathlib.Path.
  18. Nested Collections & Comprehensions (Lessons 21-26):
    • Maintain in-memory registry dictionaries mapping IDs to Data Class Instances.
    • Use List and Dictionary Comprehensions to clean and transform records.
  19. Advanced Function Parameters & Scope (Lessons 15-17):
    • Structure logic into pure modular functions with type hints, docstrings, early return Guard Clauses, and *args / **kwargs logging.
  20. Indefinite & Definite Loops (Lessons 13-14):
    • Run the interactive CLI interface inside a continuous while True menu loop.
    • Iterate through output reports using for loops with enumerate() and .items().
  21. Pattern Matching CLI Dispatcher (Lesson 12):
    • Process user CLI command tokens inside a match-case block with web server match guards:
      • case ["TEST", "GET", route_path] → Simulate GET request via Flask test_client.
      • case ["TEST", "POST", route_path, json_str] → Simulate POST request with JSON payload.
      • case ["AUDIT", "ROUTES"] → Route web request tuples using match-case pattern dispatcher.
      • case ["EXPORT", "CSV"] → Export completed route access history to CSV.
      • case ["EXIT" | "QUIT"] → Terminate session safely using a sentinel flag.
      • case _ → Output command error message.
  22. Conditionals, Formatting & Foundations (Lessons 1-11):
    • Sanitize all inputs using .strip() and .upper().
    • Format tabular reports using f-strings with field width alignment specifiers (:<15, :>10) and clear visual borders.

8. File & Workspace Directory Structure

Standard Course Workspace Layout:

Ensure all exercise files are stored inside their corresponding lesson directories:

python_mastery_course/
│
├── lesson_01/ ... lesson_56/
│
└── lesson_57/
    ├── flask_basic_routing.py
    ├── flask_request_payload_demo.py
    ├── jinja2_template_render_demo.py
    ├── match_case_flask_dispatcher.py
    ├── flask_api_task.py             <-- (Task 1)
    ├── flask_dispatcher_task.py      <-- (Task 2)
    └── web_service_os.py             <-- (Task 3: Master Review Capstone)
        

9. What We Will Learn Next

Next Up: Lesson 58 — REST APIs with FastAPI

Congratulations on completing Lesson 57! Now that you master synchronous web development and Jinja2 templating with Flask, we will explore building modern, high-performance asynchronous REST APIs using FastAPI!

In the next lesson, we will cover:

  • Introduction to Modern Asynchronous Web Frameworks and ASGI (Asynchronous Server Gateway Interface).
  • Building high-speed REST APIs using FastAPI and Uvicorn.
  • Automatic Request Validation and Serialization using Pydantic data models.
  • Interactive OpenAPI (Swagger UI) documentation auto-generation (`/docs`).
  • Asynchronous route path handlers (`async def`).
  • Combining FastAPI request models with match-case structural pattern matchers.

📝 Live Lesson Practice

HTML/CSS JavaScript Python C++ C PHP
⌨️ Practice Inputs (लाइव इनपुट भरें) (खाली होने पर RED, भरने पर GREEN underline)
💻 Code Editor (Monaco VS Code Engine)
👀 Live Preview
Address Contact

+91 7877547686

E-mail

onlinecbtportal@gmail.com

Helpline Number

+91 7877547686


Click To Download
Get it on Google Play

ऐप डाउनलोड करने
के लिए Google Play पर
उपलब्ध है

WhatsApp Chat