Skip to main content

Overview

Flask is a lightweight The Flask Application Object web application framework for Python. It is designed to make getting started quick and easy, with the ability to scale up to complex applications by providing a flexible foundation rather than a rigid structure.

The "Micro" Framework

Flask is often called a "micro" framework because it does not require particular tools or libraries. It has no database abstraction layer, form validation, or any other components where pre-existing third-party libraries provide common functions. Instead, Flask supports extensions that can add application features as if they were implemented in Flask itself.

Core Concepts

  • The Application Object: An instance of the flask.app.Flask class. It acts as the central registry for your configuration, URL rules, and template settings.
  • Routing: Flask uses decorators like @app.route() to map URLs to Python functions (view functions). It supports variable parts in URLs and multiple HTTP methods.
  • Contexts and Proxies: Flask uses Understanding the Context System to make objects like request and session available globally within a thread or task without passing them to every function.
  • Blueprints: A way to organize your application into smaller, reusable modules. flask.blueprints.Blueprint allows you to define routes and handlers that are later registered on the main app.
  • Jinja2 Templating: Integrated support for the Jinja2 engine to render dynamic HTML responses.

How It Works

When a request comes in from a WSGI server:

  1. Context Setup: Flask creates an AppContext (which includes request data) and pushes it to the internal stack.
  2. Routing: The url_adapter matches the request URL against registered rules to find the correct view function.
  3. Preprocessing: Any functions decorated with @app.before_request are executed.
  4. View Execution: The matched view function is called, returning a value that Flask converts into a flask.wrappers.Response object.
  5. Postprocessing: Functions decorated with @app.after_request are executed, allowing for header modification or logging.
  6. Teardown: The context is popped, and teardown handlers (like closing database connections) are run.

Use Cases

Simple Web Service

Create a minimal API endpoint in a single file.

from flask import Flask, jsonify

app = Flask(__name__)

@app.get("/api/health")
def health_check():
return jsonify({"status": "healthy"})

Modular Applications

Use Blueprints to split a large app into logical components.

from flask import Blueprint, Flask

auth_bp = Blueprint("auth", __name__, url_prefix="/auth")

@auth_bp.route("/login")
def login():
return "Login Page"

app = Flask(__name__)
app.register_blueprint(auth_bp)

Dynamic HTML Rendering

Render templates using Jinja2.

from flask import Flask, render_template

app = Flask(__name__)

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

When to Use Flask

  • Microservices: When you need a small, fast service with minimal overhead.
  • Prototyping: When you want to get a web app running quickly without fighting a complex framework.
  • Custom Architectures: When you want full control over which database, ORM, or validation library you use.

When to Consider Alternatives

  • Large "Standard" Apps: If you want a "batteries-included" experience where the framework makes most architectural decisions for you (e.g., Django).
  • High-Concurrency Async: While Flask supports async, frameworks built from the ground up for ASGI (like FastAPI) might be more performant for heavily asynchronous workloads.

Integration & Stack Compatibility

Flask is built on top of two core libraries:

  • Werkzeug: Implements WSGI, the standard Python interface between web servers and applications.
  • Jinja2: A powerful template engine for Python.

It integrates seamlessly with most WSGI servers like Gunicorn, uWSGI, or Waitress, and has a massive ecosystem of extensions for tasks like database integration (Flask-SQLAlchemy), form handling (Flask-WTF), and authentication (Flask-Login).

Getting Started

Limitations

  • No Built-in ORM: You must choose and configure your own database library.
  • Global State Proxies: While convenient, the use of proxies like request can sometimes make unit testing or debugging complex async code more difficult if not understood properly.
  • WSGI-First: Although it supports async, its core is synchronous WSGI, which may not be ideal for long-lived connections like WebSockets without specific extensions.