Flask Framework Tutorial
Flask is a lightweight Python web framework for building web applications and APIs. We’ll cover installation, core concepts like routing and templating, databases and forms, Blueprints for modularity, and deployment.
What is Flask Framework?\n\nFlask stands out for its minimal approach. You start with core functionality and add only what your project needs, keeping things lightweight and maintainable over time.
Flask is a micro web framework written in Python. Unlike full-stack frameworks (Django), Flask provides core tools (routing, templating) without batteries-included. Key features:\n\nFlask was created in 2009 by Armin Ronacher as an April Fool’s experiment but evolved into a robust framework. Its design philosophy favors composability—build what you need without unnecessary abstractions.
- Minimalist: Start small, add extensions (Flask-SQLAlchemy, Flask-WTF).
- Werkzeug/ Jinja2: Powers request handling and HTML templating.
- Flexible: REST APIs, web apps, microservices.
- Production-ready: Used by Netflix, LinkedIn, Pinterest.
| Framework | Size | Batteries | Learning Curve | Best For |
|---|---|---|---|---|
| Flask | 20KB | Minimal | Gentle | APIs, Prototypes |
| Django | 10MB | Full | Steeper | Enterprise Apps |
| FastAPI | 1MB | Async | Medium | High-perf APIs |
Official Docs\n\nFlask’s minimal core lets you compose your stack, but this requires thoughtful extension choices—weigh added convenience against dependency management overhead.
Flask Installation (Python 3.12+)\n\nBefore installing, create a virtual environment. This practice isolates dependencies, avoiding conflicts with other projects or system packages.
# Virtual env (recommended)
python -m venv flask-env
source flask-env/bin/activate # Linux/Mac
# flask-env\\Scripts\\activate # Windows
pip install flask
flask --version # Verify: Flask 3.0.x
Our First Flask App: Hello World
Let’s create app.py:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return '<h1>Hello, Flask Framework!</h1>'
if __name__ == '__main__':
app.run(debug=True)
Run flask run or python app.py to start the development server
Visit http://127.0.0.1:5000/ in your browser to see Hello World!
Dynamic Routes & Templates (Jinja2)
Let’s add /user/<name>:
@app.route('/user/<name>')
def user(name):
return f'<h1>Hello, {name}!</h1>'
Let’s create templates/index.html for Jinja2 templating:
<!DOCTYPE html>
<html>
<head><title>Flask App</title></head>
<body>
<h1>{{ message }}</h1>
<p>Welcome to {{ framework }} framework!</p>
</body>
</html>
Update the route:
from flask import render_template
@app.route('/')
def index():
return render_template('index.html', message='Hello Flask', framework='Flask')
Static files: static/style.css auto-served.
Forms with Flask-WTF\n\nUser input requires validation and security. Flask-WTF provides forms with built-in CSRF protection and validation, simplifying safe handling.
pip install flask-wtf
config.py:
WTF_CSRF_ENABLED = True
SECRET_KEY = 'dev' # Change to os.urandom(24) or env var in production; weak keys enable CSRF attacks
Form class:
from flask_wtf import FlaskForm
from wtforms import StringField, SubmitField
from wtforms.validators import DataRequired
class NameForm(FlaskForm):
name = StringField('Name', validators=[DataRequired()])
submit = SubmitField('Submit')
Template & route:
<form method="POST">
{{ form.hidden_tag() }}
{{ form.name.label }} {{ form.name() }}
{{ form.submit() }}
</form>
from flask import flash, redirect, url_for
# ...
@app.route('/', methods=['GET', 'POST'])
def index():
form = NameForm()
if form.validate_on_submit():
flash(f'Hello, {form.name.data}!')
return redirect(url_for('index'))
return render_template('index.html', form=form)
Database: Flask-SQLAlchemy\n\nPersistence needs an ORM for database interactions. Flask-SQLAlchemy integrates SQLAlchemy’s power with Flask conventions.
pip install flask-sqlalchemy
models.py:
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80), nullable=False)
# Init: db.create_all()
app.py: app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db' # SQLite for dev; PostgreSQL/MySQL for prod scalability ; db.init_app(app)
CLI: flask shell → db.create_all()
Blueprints: Modular Apps\n\nAs applications grow, code organization prevents monoliths. Blueprints divide apps into reusable components.
Large apps use Blueprints:
# auth_bp.py
from flask import Blueprint
auth_bp = Blueprint('auth', __name__)
@auth_bp.route('/login')
def login(): ...
# app.py: app.register_blueprint(auth_bp, url_prefix='/auth')
Deployment: Production\n\nRunning in production requires WSGI servers, process management, security. PaaS like Heroku simplifies but may lock you in; VPS or containers offer control at higher ops cost.
Heroku:
pip install gunicorn
echo "web: gunicorn app:app" > Procfile
git init; git add .; git commit -m "init"
heroku create; git push heroku main
Vercel (serverless):
vercel.json:{"builds": [{"src": "app.py", "use": "@vercel/python"}]}vercel deploy
Nginx + Gunicorn (VPS):
gunicorn -w 4 -b 0.0.0.0:8000 app:app
In production, never use app.run(); use Gunicorn/uWSGI. Set host=‘0.0.0.0’ for external access, debug=False.
Common Extensions\n\nFlask extensions address common needs. Choose based on project requirements, considering alternatives like native Python libs or other frameworks.
- REST API: Flask-RESTful/Flask-RESTX
- Auth: Flask-Login, Flask-JWT-Extended
- Admin: Flask-Admin
- Testing: pytest-flask
Best Practices
- Use
flask-cliextensions. - Environment vars:
dotenv. - Logging:
app.logger. - Error handlers:
@app.errorhandler(404)
Next: Flask Security Audit
Flask suits prototypes through production, balancing simplicity and extensibility. Experiment with these examples; common issues like port conflicts (use port=5001) or missing SECRET_KEY often arise—check logs.
Sponsored by Durable Programming
Need help maintaining or upgrading your Python application? Durable Programming specializes in keeping Python apps secure, performant, and up-to-date.
Hire Durable Programming