python
47 lines · 7 steps
Versioning a Flask API with Blueprints
Two Blueprints let v1 and v2 of a users endpoint coexist under separate URL prefixes.
Explained by
highlit
1from flask import Blueprint, jsonify, request, abort
2
3v1 = Blueprint("users_v1", __name__)
4v2 = Blueprint("users_v2", __name__)
5
6
7@v1.route("/users/<int:user_id>")
8def get_user_v1(user_id):
9 user = User.query.get_or_404(user_id)
10 return jsonify({
11 "id": user.id,
12 "name": f"{user.first_name} {user.last_name}",
13 "email": user.email,
14 })
15
16
17@v2.route("/users/<int:user_id>")
18def get_user_v2(user_id):
19 user = User.query.get_or_404(user_id)
20 return jsonify({
21 "id": user.id,
22 "first_name": user.first_name,
23 "last_name": user.last_name,
24 "email": user.email,
25 "links": {
26 "self": f"/v2/users/{user.id}",
27 "orders": f"/v2/users/{user.id}/orders",
28 },
29 })
30
31
32@v2.route("/users", methods=["POST"])
33def create_user_v2():
34 payload = request.get_json(silent=True) or {}
35 if not payload.get("email"):
36 abort(422, description="email is required")
37 user = User.create(
38 first_name=payload.get("first_name", ""),
39 last_name=payload.get("last_name", ""),
40 email=payload["email"],
41 )
42 return jsonify({"id": user.id, "email": user.email}), 201
43
44
45def register_api(app):
46 app.register_blueprint(v1, url_prefix="/v1")
47 app.register_blueprint(v2, url_prefix="/v2")
01 / 01
STEP 01
‹ swipe to step through ›
Walkthrough
Space play
←→ step
click any line
Three takeaways
- 1Separate Blueprints let you ship a new API version without breaking the old one.
- 2Mounting Blueprints under url_prefix keeps versioned routes cleanly namespaced.
- 3Changing a response shape between versions is safe when each version owns its own handler.
Related explainers
python
import time import threading from enum import Enum from functools import wraps
Building a circuit breaker in Python
circuit-breaker
resilience
decorators
Advanced
7 steps
python
from django.contrib.postgres.search import SearchQuery, SearchRank, SearchVector from django.core.cache import cache from django.db.models import F from django.http import JsonResponse
Ranked full-text search in Django
full-text-search
debouncing
caching
Advanced
9 steps
python
import os from datetime import timedelta
Class-based config in a Flask app factory
configuration
app-factory
inheritance
Intermediate
7 steps
python
import time from flask import Flask, g, request
Timing requests with Flask hooks
middleware
request-lifecycle
instrumentation
Intermediate
5 steps
python
from pathlib import Path from PIL import Image, ImageOps
Batch image resizing with Pillow
image-processing
batch-jobs
error-handling
Intermediate
8 steps
python
import base64 import hashlib import hmac import json
Building signed expiring tokens with HMAC
hmac
authentication
base64
Intermediate
7 steps
Share this explainer
Here's the card — post it anywhere.
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code
Embed this explainer
Drop the interactive walkthrough into a blog or docs. Views never cost a credit.
<iframe src="https://highlit.co/explainers/versioning-a-flask-api-with-blueprints-explained-python-996a/embed?autoplay=1" width="100%" height="520" loading="lazy" style="border:0"></iframe>
Autoplay is on by default — add ?autoplay=0 to start paused.