mirror of
https://github.com/fastapi/fastapi.git
synced 2026-05-18 13:27:45 -04:00
✨ Add support for shared/top-level parameters (dependencies, tags, etc) (#2434)
* ✨ Add Default and DefaultPlaceholder data structures to handle defaults and overrides * ✨ Add utils to get values by priority handling DefaultPlaceholders * ✨ Add support for top-level parameters in FastAPI, APIRouter, include_router including: prefix, tags, dependencies, deprecated, include_in_schema, responses, default_response_class, callbacks * ♻️ Update openapi utils to handle DefaultPlaceholder for response_class * 📝 Update bigger-application example code to use top-level params and showcase them in APIRouter, FastAPI, include_router * 📝 Update docs for Bigger Applications, include diagrams, top-level params * 🔥 Simplify code and docs for callbacks as default_response_class is no longer required * 📝 Add docs for top-level dependencies, in FastAPI() * 📝 Add docs reference to top-level dependencies in docs for decorator * ✅ Update/increase tests for Bigger Applications including shared parameters * ✅ Add tests for top-level dependencies in FastAPI() * ✅ Add tests for internal DefaultPlaceholder * ✅ Update/increase tests for callbacks with top-level parameters * ✅ Add LOTS of tests covering branches and cases for shared parameters in top-level FastAPI, path operations, include_router, APIRouter, its path operations, nested include_router, nested APIRouter, and its path operations * 🎨 Format/reorder parameters for consistency in FastAPI, APIRouter, include_router
This commit is contained in:
committed by
GitHub
parent
d550738fa2
commit
313bbe802f
11
docs_src/bigger_applications/app/dependencies.py
Normal file
11
docs_src/bigger_applications/app/dependencies.py
Normal file
@@ -0,0 +1,11 @@
|
||||
from fastapi import Header, HTTPException
|
||||
|
||||
|
||||
async def get_token_header(x_token: str = Header(...)):
|
||||
if x_token != "fake-super-secret-token":
|
||||
raise HTTPException(status_code=400, detail="X-Token header invalid")
|
||||
|
||||
|
||||
async def get_query_token(token: str):
|
||||
if token != "jessica":
|
||||
raise HTTPException(status_code=400, detail="No Jessica token provided")
|
||||
8
docs_src/bigger_applications/app/internal/admin.py
Normal file
8
docs_src/bigger_applications/app/internal/admin.py
Normal file
@@ -0,0 +1,8 @@
|
||||
from fastapi import APIRouter
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.post("/")
|
||||
async def update_admin():
|
||||
return {"message": "Admin getting schwifty"}
|
||||
@@ -1,20 +1,23 @@
|
||||
from fastapi import Depends, FastAPI, Header, HTTPException
|
||||
from fastapi import Depends, FastAPI
|
||||
|
||||
from .dependencies import get_query_token, get_token_header
|
||||
from .internal import admin
|
||||
from .routers import items, users
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
|
||||
async def get_token_header(x_token: str = Header(...)):
|
||||
if x_token != "fake-super-secret-token":
|
||||
raise HTTPException(status_code=400, detail="X-Token header invalid")
|
||||
app = FastAPI(dependencies=[Depends(get_query_token)])
|
||||
|
||||
|
||||
app.include_router(users.router)
|
||||
app.include_router(items.router)
|
||||
app.include_router(
|
||||
items.router,
|
||||
prefix="/items",
|
||||
tags=["items"],
|
||||
admin.router,
|
||||
prefix="/admin",
|
||||
tags=["admin"],
|
||||
dependencies=[Depends(get_token_header)],
|
||||
responses={404: {"description": "Not found"}},
|
||||
responses={418: {"description": "I'm a teapot"}},
|
||||
)
|
||||
|
||||
|
||||
@app.get("/")
|
||||
async def root():
|
||||
return {"message": "Hello Bigger Applications!"}
|
||||
|
||||
@@ -1,16 +1,28 @@
|
||||
from fastapi import APIRouter, HTTPException
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
|
||||
router = APIRouter()
|
||||
from ..dependencies import get_token_header
|
||||
|
||||
router = APIRouter(
|
||||
prefix="/items",
|
||||
tags=["items"],
|
||||
dependencies=[Depends(get_token_header)],
|
||||
responses={404: {"description": "Not found"}},
|
||||
)
|
||||
|
||||
|
||||
fake_items_db = {"plumbus": {"name": "Plumbus"}, "gun": {"name": "Portal Gun"}}
|
||||
|
||||
|
||||
@router.get("/")
|
||||
async def read_items():
|
||||
return [{"name": "Item Foo"}, {"name": "item Bar"}]
|
||||
return fake_items_db
|
||||
|
||||
|
||||
@router.get("/{item_id}")
|
||||
async def read_item(item_id: str):
|
||||
return {"name": "Fake Specific Item", "item_id": item_id}
|
||||
if item_id not in fake_items_db:
|
||||
raise HTTPException(status_code=404, detail="Item not found")
|
||||
return {"name": fake_items_db[item_id]["name"], "item_id": item_id}
|
||||
|
||||
|
||||
@router.put(
|
||||
@@ -19,6 +31,8 @@ async def read_item(item_id: str):
|
||||
responses={403: {"description": "Operation forbidden"}},
|
||||
)
|
||||
async def update_item(item_id: str):
|
||||
if item_id != "foo":
|
||||
raise HTTPException(status_code=403, detail="You can only update the item: foo")
|
||||
return {"item_id": item_id, "name": "The Fighters"}
|
||||
if item_id != "plumbus":
|
||||
raise HTTPException(
|
||||
status_code=403, detail="You can only update the item: plumbus"
|
||||
)
|
||||
return {"item_id": item_id, "name": "The great Plumbus"}
|
||||
|
||||
@@ -5,7 +5,7 @@ router = APIRouter()
|
||||
|
||||
@router.get("/users/", tags=["users"])
|
||||
async def read_users():
|
||||
return [{"username": "Foo"}, {"username": "Bar"}]
|
||||
return [{"username": "Rick"}, {"username": "Morty"}]
|
||||
|
||||
|
||||
@router.get("/users/me", tags=["users"])
|
||||
|
||||
25
docs_src/dependencies/tutorial012.py
Normal file
25
docs_src/dependencies/tutorial012.py
Normal file
@@ -0,0 +1,25 @@
|
||||
from fastapi import Depends, FastAPI, Header, HTTPException
|
||||
|
||||
|
||||
async def verify_token(x_token: str = Header(...)):
|
||||
if x_token != "fake-super-secret-token":
|
||||
raise HTTPException(status_code=400, detail="X-Token header invalid")
|
||||
|
||||
|
||||
async def verify_key(x_key: str = Header(...)):
|
||||
if x_key != "fake-super-secret-key":
|
||||
raise HTTPException(status_code=400, detail="X-Key header invalid")
|
||||
return x_key
|
||||
|
||||
|
||||
app = FastAPI(dependencies=[Depends(verify_token), Depends(verify_key)])
|
||||
|
||||
|
||||
@app.get("/items/")
|
||||
async def read_items():
|
||||
return [{"item": "Portal Gun"}, {"item": "Plumbus"}]
|
||||
|
||||
|
||||
@app.get("/users/")
|
||||
async def read_users():
|
||||
return [{"username": "Rick"}, {"username": "Morty"}]
|
||||
@@ -1,7 +1,6 @@
|
||||
from typing import Optional
|
||||
|
||||
from fastapi import APIRouter, FastAPI
|
||||
from fastapi.responses import JSONResponse
|
||||
from pydantic import BaseModel, HttpUrl
|
||||
|
||||
app = FastAPI()
|
||||
@@ -23,7 +22,7 @@ class InvoiceEventReceived(BaseModel):
|
||||
ok: bool
|
||||
|
||||
|
||||
invoices_callback_router = APIRouter(default_response_class=JSONResponse)
|
||||
invoices_callback_router = APIRouter()
|
||||
|
||||
|
||||
@invoices_callback_router.post(
|
||||
|
||||
Reference in New Issue
Block a user