Flask Basics
Hello World
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
return 'Hello, World!'
if __name__ == '__main__':
app.run(debug=True)
Route Decorators
@app.route('/')
def index():
return 'Home Page'
@app.route('/about')
def about():
return 'About Page'
# Variable rules
@app.route('/user/<username>')
def user_profile(username):
return f'Profile: {username}'
@app.route('/post/<int:post_id>')
def post(post_id):
return f'Post {post_id}'
# HTTP methods
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
return 'Logged in!'
return 'Login form'
Request Object
from flask import request
@app.route('/search')
def search():
query = request.args.get('q', '')
page = request.args.get('page', 1, type=int)
return f'Search: {query}, Page: {page}'
@app.route('/data', methods=['POST'])
def receive_data():
data = request.get_json()
return {'received': data}
Responses
from flask import jsonify, make_response
# Return string
return 'Hello'
# Return JSON
return jsonify({'message': 'Hello'})
# Return with status code
return jsonify({'error': 'Not found'}), 404
# Return with headers
response = make_response(jsonify({'data': 'value'}))
response.headers['X-Custom'] = 'header'
return response
Templates & Forms
Jinja2 Templates
from flask import render_template
@app.route('/user/<name>')
def user(name):
return render_template('user.html', name=name, age=30)
Template Syntax
<!-- templates/user.html -->
<!DOCTYPE html>
<html>
<head><title>{{ name }}</title></head>
<body>
<h1>Hello, {{ name }}!</h1>
<p>Age: {{ age }}</p>
{% if age >= 18 %}
<p>Adult</p>
{% else %}
<p>Minor</p>
{% endif %}
<ul>
{% for item in items %}
<li>{{ item }}</li>
{% endfor %}
</ul>
</body>
</html>
Template Inheritance
<!-- templates/base.html -->
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}My App{% endblock %}</title>
</head>
<body>
<nav>Navigation</nav>
{% block content %}{% endblock %}
<footer>Footer</footer>
</body>
</html>
<!-- templates/user.html -->
{% extends 'base.html' %}
{% block title %}{{ name }}{% endblock %}
{% block content %}
<h1>Hello, {{ name }}!</h1>
{% endblock %}
Forms
from flask import request, redirect, url_for, flash
@app.route('/login', methods=['GET', 'POST'])
def login():
if request.method == 'POST':
username = request.form['username']
password = request.form['password']
if authenticate(username, password):
flash('Logged in successfully!')
return redirect(url_for('index'))
else:
flash('Invalid credentials')
return render_template('login.html')
WTForms
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired, Email
class LoginForm(FlaskForm):
email = StringField('Email', validators=[DataRequired(), Email()])
password = PasswordField('Password', validators=[DataRequired()])
submit = SubmitField('Login')
@app.route('/login', methods=['GET', 'POST'])
def login():
form = LoginForm()
if form.validate_on_submit():
# Process form
return redirect(url_for('index'))
return render_template('login.html', form=form)
Blueprints & Organization
What are Blueprints?
Blueprints organize Flask applications into modular components.
# auth/routes.py
from flask import Blueprint, request, jsonify
auth_bp = Blueprint('auth', __name__)
@auth_bp.route('/login', methods=['POST'])
def login():
data = request.get_json()
# ... authentication logic
return jsonify({'token': 'abc123'})
@auth_bp.route('/register', methods=['POST'])
def register():
data = request.get_json()
# ... registration logic
return jsonify({'message': 'User created'}), 201
Registering Blueprints
# app.py
from flask import Flask
from auth.routes import auth_bp
from users.routes import users_bp
def create_app():
app = Flask(__name__)
# Register blueprints
app.register_blueprint(auth_bp, url_prefix='/auth')
app.register_blueprint(users_bp, url_prefix='/users')
return app
app = create_app()
Project Structure
myapp/
├── app.py
├── auth/
│ ├── __init__.py
│ ├── routes.py
│ └── forms.py
├── users/
│ ├── __init__.py
│ ├── routes.py
│ └── models.py
├── templates/
│ ├── base.html
│ └── auth/
│ └── login.html
└── static/
├── css/
└── js/
Error Handling
@app.errorhandler(404)
def not_found(error):
return jsonify({'error': 'Not found'}), 404
@app.errorhandler(500)
def internal_error(error):
return jsonify({'error': 'Internal server error'}), 500
# Custom exceptions
class APIError(Exception):
def __init__(self, message, status_code=400):
self.message = message
self.status_code = status_code
@app.errorhandler(APIError)
def handle_api_error(error):
return jsonify({'error': error.message}), error.status_code
Configuration
import os
class Config:
SECRET_KEY = os.getenv('SECRET_KEY', 'dev-secret')
DEBUG = False
DATABASE_URI = os.getenv('DATABASE_URI')
class DevelopmentConfig(Config):
DEBUG = True
class ProductionConfig(Config):
DEBUG = False
config = {
'development': DevelopmentConfig,
'production': ProductionConfig,
'default': DevelopmentConfig
}
app = Flask(__name__)
app.config.from_object(config[os.getenv('FLASK_ENV', 'default')])