Cheatsheet#
Flask is a lightweight WSGI web application framework written in Python. Created by Armin Ronacher in 2010, Flask is considered a microframework because it doesnβt 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.
π New to App-Generator? Sign IN with GitHub or Generate Web Apps in no time (free service).
Basic Application Setup and Routing
from flask import Flask, request, jsonify, render_template
from werkzeug.middleware.proxy_fix import ProxyFix
# Basic app setup
app = Flask(__name__)
app.wsgi_app = ProxyFix(app.wsgi_app)
# Configuration
app.config['SECRET_KEY'] = 'your-secret-key'
app.config['DEBUG'] = True
# Basic routes
@app.route('/')
def home():
return 'Hello, World!'
# Multiple HTTP methods
@app.route('/api/resource', methods=['GET', 'POST'])
def handle_resource():
if request.method == 'POST':
return jsonify({"message": "Created"}), 201
return jsonify({"message": "Retrieved"})
# URL variables
@app.route('/user/<username>')
def show_user(username):
return f'User: {username}'
# URL variables with converters
@app.route('/post/<int:post_id>')
def show_post(post_id):
return f'Post: {post_id}'
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
Request Handling and Response
from flask import request, jsonify, make_response, abort
@app.route('/api/data', methods=['POST'])
def handle_data():
# Access JSON data
data = request.get_json()
# Access form data
form_data = request.form.get('field_name')
# Access URL parameters
param = request.args.get('param')
# Access headers
header_value = request.headers.get('X-Custom-Header')
# Custom response
response = make_response(jsonify({'message': 'Success'}))
response.headers['X-Custom-Header'] = 'Value'
response.status_code = 200
return response
# Error handling
@app.errorhandler(404)
def not_found_error(error):
return jsonify({'error': 'Resource not found'}), 404
@app.errorhandler(500)
def internal_error(error):
return jsonify({'error': 'Internal server error'}), 500
# Abort example
@app.route('/resource/<id>')
def get_resource(id):
if not valid_resource(id):
abort(404)
return jsonify({'id': id})
Templates and Static Files
from flask import render_template, send_file, url_for
# Basic template rendering
@app.route('/template')
def show_template():
return render_template('index.html',
title='Home',
user={'name': 'John'})
# Template with loops and conditions
@app.route('/items')
def show_items():
items = ['item1', 'item2', 'item3']
return render_template('items.html',
items=items,
show_items=True)
# Static files
@app.route('/static-file')
def serve_static():
return send_file('static/file.pdf')
# Template inheritance example
"""
# base.html
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}{% endblock %}</title>
</head>
<body>
{% block content %}{% endblock %}
</body>
</html>
# child.html
{% extends "base.html" %}
{% block title %}Page Title{% endblock %}
{% block content %}
<h1>Content goes here</h1>
{% endblock %}
"""
Database Integration (SQLAlchemy)
from flask_sqlalchemy import SQLAlchemy
# Database setup
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///database.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
# Models
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True, nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
posts = db.relationship('Post', backref='author', lazy=True)
class Post(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(120), nullable=False)
content = db.Column(db.Text, nullable=False)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
# Database operations
@app.route('/create_user', methods=['POST'])
def create_user():
data = request.get_json()
new_user = User(username=data['username'], email=data['email'])
db.session.add(new_user)
db.session.commit()
return jsonify({'message': 'User created'})
# Query examples
@app.route('/users')
def get_users():
users = User.query.all()
return jsonify([{
'id': user.id,
'username': user.username
} for user in users])
Authentication and Sessions
from flask_login import LoginManager, UserMixin, login_user, login_required, current_user
from werkzeug.security import generate_password_hash, check_password_hash
from flask import session
# Login manager setup
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'
class User(UserMixin, db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True)
password_hash = db.Column(db.String(120))
def set_password(self, password):
self.password_hash = generate_password_hash(password)
def check_password(self, password):
return check_password_hash(self.password_hash, password)
@login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))
# Login route
@app.route('/login', methods=['POST'])
def login():
data = request.get_json()
user = User.query.filter_by(username=data['username']).first()
if user and user.check_password(data['password']):
login_user(user)
return jsonify({'message': 'Logged in successfully'})
return jsonify({'message': 'Invalid credentials'}), 401
# Protected route
@app.route('/protected')
@login_required
def protected_route():
return jsonify({'message': f'Hello {current_user.username}'})
# Session handling
@app.route('/set_session')
def set_session():
session['key'] = 'value'
return 'Session set'
@app.route('/get_session')
def get_session():
return session.get('key', 'not set')
Forms and Validation
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired, Email, Length
# Form class
class RegistrationForm(FlaskForm):
username = StringField('Username',
validators=[DataRequired(), Length(min=4, max=20)])
email = StringField('Email',
validators=[DataRequired(), Email()])
password = PasswordField('Password',
validators=[DataRequired(), Length(min=6)])
submit = SubmitField('Register')
# Form handling
@app.route('/register', methods=['GET', 'POST'])
def register():
form = RegistrationForm()
if form.validate_on_submit():
user = User(
username=form.username.data,
email=form.email.data
)
user.set_password(form.password.data)
db.session.add(user)
db.session.commit()
return redirect(url_for('login'))
return render_template('register.html', form=form)
Blueprints and Application Factory
# auth/routes.py
from flask import Blueprint
auth = Blueprint('auth', __name__)
@auth.route('/login')
def login():
return 'Login'
# admin/routes.py
admin = Blueprint('admin', __name__, url_prefix='/admin')
@admin.route('/')
def admin_index():
return 'Admin Index'
# Application factory
def create_app(config_object=None):
app = Flask(__name__)
if config_object:
app.config.from_object(config_object)
# Initialize extensions
db.init_app(app)
login_manager.init_app(app)
# Register blueprints
app.register_blueprint(auth)
app.register_blueprint(admin)
return app
API Development and RESTful Resources
from flask_restful import Api, Resource, reqparse
api = Api(app)
# Request parser
parser = reqparse.RequestParser()
parser.add_argument('name', type=str, required=True)
parser.add_argument('age', type=int)
# Resource class
class UserResource(Resource):
def get(self, user_id):
user = User.query.get_or_404(user_id)
return {'name': user.name, 'age': user.age}
def put(self, user_id):
args = parser.parse_args()
user = User.query.get_or_404(user_id)
user.name = args['name']
user.age = args['age']
db.session.commit()
return {'message': 'User updated'}
def delete(self, user_id):
user = User.query.get_or_404(user_id)
db.session.delete(user)
db.session.commit()
return {'message': 'User deleted'}
# Add resource to API
api.add_resource(UserResource, '/api/user/<int:user_id>')
Testing
import unittest
from app import create_app, db
class TestConfig:
TESTING = True
SQLALCHEMY_DATABASE_URI = 'sqlite:///:memory:'
class TestCase(unittest.TestCase):
def setUp(self):
self.app = create_app(TestConfig)
self.client = self.app.test_client()
self.ctx = self.app.app_context()
self.ctx.push()
db.create_all()
def tearDown(self):
db.session.remove()
db.drop_all()
self.ctx.pop()
def test_home_page(self):
response = self.client.get('/')
self.assertEqual(response.status_code, 200)
def test_create_user(self):
response = self.client.post('/api/users',
json={'username': 'test',
'email': 'test@test.com'})
self.assertEqual(response.status_code, 201)
Deployment and Configuration
# config.py
class Config:
SECRET_KEY = 'dev'
SQLALCHEMY_DATABASE_URI = 'sqlite:///app.db'
MAIL_SERVER = 'smtp.googlemail.com'
MAIL_PORT = 587
MAIL_USE_TLS = True
MAIL_USERNAME = 'your-email@gmail.com'
MAIL_PASSWORD = 'your-password'
class ProductionConfig(Config):
DEBUG = False
SQLALCHEMY_DATABASE_URI = os.environ.get('DATABASE_URL')
class DevelopmentConfig(Config):
DEBUG = True
class TestingConfig(Config):
TESTING = True
SQLALCHEMY_DATABASE_URI = 'sqlite:///:memory:'
# WSGI file (wsgi.py)
from app import create_app
app = create_app(ProductionConfig)
if __name__ == '__main__':
app.run()
# Gunicorn configuration
"""
# gunicorn.conf.py
workers = 4
bind = '0.0.0.0:8000'
worker_class = 'gevent'
timeout = 120
"""
Pro Tips
Use application factory pattern for larger applications
Implement proper error handling and logging
Use environment variables for sensitive configuration
Implement proper password hashing
Use Flask-Migrate for database migrations
Implement proper CSRF protection
Use blueprints to organize code
Implement proper caching strategy
Use Flask-Admin for quick admin interfaces
Write comprehensive tests
Use Flask-Caching for performance optimization
Implement proper security headers
Links#
π New to App-Generator? Join our 10k+ Community using GitHub One-Click SignIN.
π
Download
products and start fast a new projectπ Bootstrap your startUp, MVP or Legacy project with a custom development sprint