text: from fastapi import (
      FastAPI, Depends, Query, Header,
      HTTPException, status
  )
  from typing import Tuple, Dict, Optional
  from pydantic import BaseModel
  
  
  app = FastAPI()
  
  
  explain = '''
  - Internally, the Header "dependency function" has some logic to automatically get the request object
  - don't know how, just ask for the value we need
  - "the way to wrap some logic that will retrieve some sub-values or sub-objects, make something with them,
  and finally return a value that will be injected into the endpoint calling it"
  - Advance:
      + The intent is clear
      + clear separation of concern: endpoint logic vs generic logic
      + generate the OpenAPI schema
  - When to use:
      + need utility logic to retrieve or validate data
      + security checks
      + call external logic need several times across app
  - How create:
      + defined either as a function or as a callable class
  - Depends execute function argument when the endpoint is called.
  - In a REST API, you'll typically have endpoints to get, update, and delete a single object
      given its identifier in the path
  -
  '''
  
  
  '''
  @app.get("/")
  async def header(user_agent: str = Header(...)):
      return {"user_agent": user_agent}
  
  
  # dependency function
  async def pagination(skip: int = 0, limit: int = 10) -> Tuple[int, int]:
      return (skip, limit)    # query parameters on our endpoint
  
  async def pagination(
      skip: int = Query(0, ge=0),     # validation constraint
      limit: int = Query(50, ge=0),
  ) -> Tuple[int, int]:
      capped_limit = min(100, limit)
      return (skip, capped_limit)
  
  
  @app.get("/items")
  # function result as a default value
  async def list_items(p: Tuple[int, int] = Depends(pagination)):
      skip, limit = p
      return {"skip": skip, "limit": limit}
  
  
  @app.get("/things")
  async def list_things(p: Tuple[int, int] = Depends(pagination)):    # can now reuse it
      skip, limit = p
      return {"skip": skip, "limit": limit}
  # '''
  
  
  class Post(BaseModel):
      id: int
      title: str
      content: str
  
  
  class PostUpdate(BaseModel):
      title: Optional[str]
      content: Optional[str]
  
  
  class DummyDatabase:
      posts: Dict[int, Post] = {}
  
  
  db = DummyDatabase()
  db.posts = {
      1: Post(id=1, title="Post 1", content="Content 1"),
      2: Post(id=2, title="Post 2", content="Content 2"),
      3: Post(id=3, title="Post 3", content="Content 3"),
  }
  
  
  async def get_post_or_404(id: int) -> Post:
      try:
          return db.posts[id]
      except KeyError:
          raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)
  
  
  @app.get("/posts/{id}")
  async def get(post: Post = Depends(get_post_or_404)):
      return post
  
  
  @app.patch("/posts/{id}")
  async def update(post_update: PostUpdate, post: Post = Depends(get_post_or_404)):
      updated_post = post.copy(update=post_update.dict())
      db.posts[post.id] = updated_post
      return updated_post
  
  
  @app.delete("/posts/{id}", status_code=status.HTTP_404_NOT_FOUND)
  async def delete(post: Post = Depends(get_post_or_404)):
      db.posts.pop(post.id)
  