python 39 lines · 7 steps

Gating a FastAPI route behind a feature flag

A dependency factory builds a per-flag guard that hides experimental endpoints from users who lack access.

Explained by highlit
1from fastapi import APIRouter, Depends, HTTPException, status
2 
3from app.config import settings
4from app.dependencies import get_current_user
5from app.models import User
6from app.schemas import RecommendationOut
7from app.services import recommendations
8 
9router = APIRouter(prefix="/experimental", tags=["experimental"])
10 
11 
12def require_feature(flag: str):
13 async def _guard(user: User = Depends(get_current_user)) -> None:
14 if flag in user.feature_overrides:
15 if not user.feature_overrides[flag]:
16 raise HTTPException(
17 status_code=status.HTTP_404_NOT_FOUND,
18 detail="Not found",
19 )
20 return
21 if not settings.feature_flags.get(flag, False):
22 raise HTTPException(
23 status_code=status.HTTP_404_NOT_FOUND,
24 detail="Not found",
25 )
26 
27 return _guard
28 
29 
30@router.get(
31 "/recommendations",
32 response_model=list[RecommendationOut],
33 dependencies=[Depends(require_feature("smart_recommendations"))],
34)
35async def list_recommendations(
36 limit: int = 20,
37 user: User = Depends(get_current_user),
38) -> list[RecommendationOut]:
39 return await recommendations.for_user(user, limit=limit)
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1A function that returns a dependency lets you parameterize FastAPI guards without duplicating logic per route.
  2. 2Returning 404 instead of 403 hides an endpoint's existence from users who aren't entitled to it.
  3. 3Per-user overrides checked before global defaults let you selectively enable or disable a flag for individual accounts.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Gating a FastAPI route behind a feature flag — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code