Flask Introduction

What Flask is, how it compares to Django, and how to install it and run your first app.

What is Flask?

Flask is a lightweight WSGI web framework for Python, originally released by Armin Ronacher in 2010. Flask calls itself a microframework, but "micro" doesn't mean "toy" or "limited" — it means the core framework makes very few decisions on your behalf. There's no bundled ORM, no bundled admin panel, no bundled authentication system. Flask hands you routing, request/response handling, and template rendering, and lets you choose everything else yourself: which database library to use, which form validation approach fits, which authentication scheme makes sense for your app.

That minimalism is a deliberate design philosophy, built on two smaller libraries doing the real work under the hood:

  • Werkzeug — a WSGI utility library handling the low-level HTTP request/response plumbing.
  • Jinja2 — the templating engine Flask uses to render HTML.

Because Flask stays out of your way, it's a common choice for small APIs, microservices, prototypes, and any project where a team wants full control over structure rather than inheriting one.

Flask vs Django: two philosophies

Flask and Django are the two most common Python web frameworks, and they sit at opposite ends of the same spectrum:

Flask Django
Philosophy Micro-framework — bring your own pieces Batteries-included — ORM, admin, auth ship built in
ORM Not included (commonly paired with SQLAlchemy) Django ORM included
Admin panel Not included Auto-generated admin site included
Project layout Unopinionated — you decide A generated project/app structure
Best for Small APIs, microservices, projects that want full control Larger, more conventional applications that want structure out of the box
Learning curve Gentle to start, more decisions as the app grows More to learn up front, fewer decisions later

Neither is objectively better — Flask trades built-in structure for flexibility, Django trades some flexibility for a productive, consistent structure. Plenty of real production systems are built on each.

Installing Flask

Install Flask with pip, ideally inside a virtual environment so its dependencies don't leak into (or clash with) other projects:

Bash
python3 -m venv venv
source venv/bin/activate      # on Windows: venv\Scripts\activate
pip install flask

Confirm the install:

Bash
python3 -c "import flask; print(flask.__version__)"
# 3.0.3

Your first Flask app

A complete, runnable Flask application fits in a few lines:

Python
# app.py
from flask import Flask

app = Flask(__name__)

@app.route("/")
def home():
    return "Hello, World!"

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

Flask(__name__) creates the application object — passing __name__ lets Flask figure out the root path of your app so it can find things like the templates/ and static/ folders relative to it. The @app.route("/") decorator registers home() as the function that runs whenever a request comes in for /. Whatever the function returns becomes the HTTP response body — here, a plain string.

Running the development server

There are two common ways to start the app during development.

Directly with Python (using the app.run() call at the bottom of the file):

Bash
python3 app.py

With the flask CLI, which doesn't require an if __name__ == "__main__" block at all:

Bash
export FLASK_APP=app.py       # on Windows: set FLASK_APP=app.py
export FLASK_DEBUG=1
flask run

Either way, visiting http://127.0.0.1:5000 in a browser shows Hello, World!. debug=True (or FLASK_DEBUG=1) turns on the auto-reloader (the server restarts itself whenever you save a code change) and an interactive in-browser debugger for unhandled exceptions — both are enormously useful while developing and both must be off in production.

Common mistakes

  • Leaving debug=True active in a deployed app — the interactive debugger it enables can execute arbitrary Python code from a browser, which is a severe security hole outside of local development.
  • Running python3 app.py / flask run in production — the built-in development server is single-threaded and explicitly documented as unsuitable for production traffic; real deployments sit behind a production WSGI server like Gunicorn or uWSGI.
  • Installing Flask globally instead of inside a virtual environment, leading to version conflicts between unrelated projects on the same machine.

Interview questions

Q: What does "WSGI" mean, and why does it matter for Flask? WSGI (Web Server Gateway Interface) is a standard Python spec describing how a web server talks to a Python web application — a common interface so any WSGI-compliant server (Gunicorn, uWSGI, Waitress) can run any WSGI-compliant framework (Flask, Django). Flask is built directly on Werkzeug's WSGI implementation, which is why it can run behind any standard Python application server rather than needing a custom protocol of its own.

Q: If Flask calls itself a "microframework," how do real, large production apps get built with it? "Micro" describes the small, unopinionated core — not a limit on what you can build. Larger Flask apps add exactly the structure they need through extensions and conventions (Flask-SQLAlchemy for an ORM, Flask-Login for auth, blueprints to split the app into modules, an application factory for configuration) rather than inheriting a one-size-fits-all structure the way Django provides out of the box.