Flask remains one of the most popular Python web frameworks in 2026, known for its simplicity and flexibility. This guide walks you through setting up a modern Flask project using the latest tools and best practices.
What’s New in 2026?
uv - Blazing fast Python package manager (replaces pip/poetry)
Flask 3.x - Native async support, improved typing
SQLAlchemy 2.0 - Modern ORM with better type hints
Pydantic v2 - Fast data validation
Ruff - All-in-one linter and formatter (replaces black, isort, flake8)
# Or use separate components DB_HOST=localhost DB_PORT=5432 DB_USER=postgres DB_PASSWORD=password DB_NAME=flask_modern
Step 6: Set Up Extensions
Create app/extensions.py:
from flask_sqlalchemy import SQLAlchemy from flask_migrate import Migrate
db = SQLAlchemy() migrate = Migrate()
Step 7: Create Models
Create app/models/__init__.py:
from .user import User
__all__ = ["User"]
Create app/models/user.py:
from datetime import datetime, UTC from sqlalchemy import String, Boolean, DateTime from sqlalchemy.orm import Mapped, mapped_column from app.extensions import db
from flask import request, jsonify from pydantic import ValidationError from app.api import api_bp from app.schemas import UserCreate, UserUpdate, UserResponse from app.services import UserService
@api_bp.route("/users", methods=["GET"]) defget_users(): skip = request.args.get("skip", 0, type=int) limit = request.args.get("limit", 100, type=int) users = UserService.get_all(skip=skip, limit=limit) return jsonify([UserResponse.model_validate(u).model_dump() for u in users])
@api_bp.route("/users/<int:user_id>", methods=["GET"]) defget_user(user_id: int): user = UserService.get_by_id(user_id) ifnot user: return jsonify({"error": "User not found"}), 404 return jsonify(UserResponse.model_validate(user).model_dump())
@api_bp.route("/users", methods=["POST"]) defcreate_user(): try: data = UserCreate.model_validate(request.json) except ValidationError as e: return jsonify({"error": e.errors()}), 422
if UserService.get_by_email(data.email): return jsonify({"error": "Email already registered"}), 400
user = UserService.create(data) return jsonify(UserResponse.model_validate(user).model_dump()), 201
@api_bp.route("/users/<int:user_id>", methods=["PATCH"]) defupdate_user(user_id: int): user = UserService.get_by_id(user_id) ifnot user: return jsonify({"error": "User not found"}), 404
try: data = UserUpdate.model_validate(request.json) except ValidationError as e: return jsonify({"error": e.errors()}), 422
# Flask CLI uv run flask --help# Show commands uv run flask routes # List all routes uv run flask shell # Interactive shell
# Database migrations uv run flask db init # Initialize migrations uv run flask db migrate -m "msg"# Create migration uv run flask db upgrade # Apply migrations uv run flask db downgrade # Rollback migration
# Testing uv run pytest -v # Verbose output uv run pytest -x # Stop on first failure uv run pytest -k "test_create"# Run matching tests
Why This Stack?
Tool
Why Use It
uv
10-100x faster than pip, built-in venv management
Flask 3.x
Mature, flexible, great ecosystem
SQLAlchemy 2.0
Type-safe ORM, excellent performance
Pydantic v2
Fast validation, great DX
Ruff
Single tool replaces black + isort + flake8
pytest
Industry standard, great plugins
Next Steps
Add authentication (Flask-JWT-Extended or Authlib)
Add caching (Flask-Caching with Redis)
Add background tasks (Celery or RQ)
Add API documentation (Flask-RESTX or Flasgger)
Set up CI/CD (GitHub Actions)
Add logging and monitoring
Conclusion
This modern Flask setup gives you a solid foundation for building production-ready applications in 2026. The combination of uv for package management, SQLAlchemy 2.0 for database operations, Pydantic for validation, and Ruff for code quality creates a fast, type-safe, and maintainable codebase.
The project structure separates concerns cleanly: models for database schema, schemas for validation, services for business logic, and API routes for HTTP handling. This makes the code easy to test and extend.
Learn how to use uv, the blazingly fast Python package and project manager written in Rust, to install Python, manage dependencies, and streamline your development workflow.