mirror of
https://github.com/fastapi/fastapi.git
synced 2026-09-14 13:36:21 +08:00
05ca41cfd1
* ➕ Add mkdocstrings and griffe-typingdoc to dependencies * 🔧 Add mkdocstrings configs to MkDocs * 📝 Add first WIP reference page * ⬆️ Upgrade typing-extensions to the minimum version including Doc() * 📝 Add docs to FastAPI parameters * 📝 Add docstrings for OpenAPI docs utils * 📝 Add docstrings for security utils * 📝 Add docstrings for UploadFile * 📝 Update docstrings in FastAPI class * 📝 Add docstrings for path operation methods * 📝 Add docstring for jsonable_encoder * 📝 Add docstrings for exceptions * 📝 Add docstsrings for parameter functions * 📝 Add docstrings for responses * 📝 Add docstrings for APIRouter * ♻️ Sub-class BackgroundTasks to document it with docstrings * 📝 Update usage of background tasks in dependencies * ✅ Update tests with new deprecation warnings * 📝 Add new reference docs * 🔧 Update MkDocs with new reference docs * ✅ Update pytest fixture, deprecation is raised only once * 🎨 Update format for types in exceptions.py * ♻️ Update annotations in BackgroundTask, `Annotated` can't take ParamSpec's P.args or P.kwargs * ✏️ Fix typos caught by @pawamoy * 🔧 Update and fix MkDocstrings configs from @pawamoy tips * 📝 Update reference docs * ✏️ Fix typos found by @pawamoy * ➕ Add HTTPX as a dependency for docs, for the TestClient * 🔧 Update MkDocs config, rename websockets reference * 🔇 Add type-ignores for Doc as the stubs haven't been released for mypy * 🔥 Remove duplicated deprecated notice * 🔇 Remove typing error for unreleased stub in openapi/docs.py * ✅ Add tests for UploadFile for coverage * ⬆️ Upgrade griffe-typingdoc==0.2.2 * 📝 Refactor docs structure * 🔨 Update README generation with new index frontmatter and style * 🔨 Update generation of languages, remove from top menu, keep in lang menu * 📝 Add OpenAPI Pydantic models * 🔨 Update docs script to not translate Reference and Release Notes * 🔧 Add reference for OpenAPI models * 🔧 Update MkDocs config for mkdocstrings insiders * 👷 Install mkdocstring insiders in CI for docs * 🐛 Fix MkDocstrings insiders install URL * ➕ Move dependencies shared by docs and tests to its own requirements file * 👷 Update cache keys for test and docs dependencies * 📝 Remove no longer needed __init__ placeholder docstrings * 📝 Move docstring for APIRouter to the class level (not __init__ level) * 🔥 Remove no longer needed dummy placeholder __init__ docstring
112 lines
3.2 KiB
Python
112 lines
3.2 KiB
Python
from contextlib import asynccontextmanager
|
|
from typing import AsyncGenerator, Dict
|
|
|
|
import pytest
|
|
from fastapi import APIRouter, FastAPI
|
|
from fastapi.testclient import TestClient
|
|
from pydantic import BaseModel
|
|
|
|
|
|
class State(BaseModel):
|
|
app_startup: bool = False
|
|
app_shutdown: bool = False
|
|
router_startup: bool = False
|
|
router_shutdown: bool = False
|
|
sub_router_startup: bool = False
|
|
sub_router_shutdown: bool = False
|
|
|
|
|
|
@pytest.fixture
|
|
def state() -> State:
|
|
return State()
|
|
|
|
|
|
@pytest.mark.filterwarnings(
|
|
r"ignore:\s*on_event is deprecated, use lifespan event handlers instead.*:DeprecationWarning"
|
|
)
|
|
def test_router_events(state: State) -> None:
|
|
app = FastAPI()
|
|
|
|
@app.get("/")
|
|
def main() -> Dict[str, str]:
|
|
return {"message": "Hello World"}
|
|
|
|
@app.on_event("startup")
|
|
def app_startup() -> None:
|
|
state.app_startup = True
|
|
|
|
@app.on_event("shutdown")
|
|
def app_shutdown() -> None:
|
|
state.app_shutdown = True
|
|
|
|
router = APIRouter()
|
|
|
|
@router.on_event("startup")
|
|
def router_startup() -> None:
|
|
state.router_startup = True
|
|
|
|
@router.on_event("shutdown")
|
|
def router_shutdown() -> None:
|
|
state.router_shutdown = True
|
|
|
|
sub_router = APIRouter()
|
|
|
|
@sub_router.on_event("startup")
|
|
def sub_router_startup() -> None:
|
|
state.sub_router_startup = True
|
|
|
|
@sub_router.on_event("shutdown")
|
|
def sub_router_shutdown() -> None:
|
|
state.sub_router_shutdown = True
|
|
|
|
router.include_router(sub_router)
|
|
app.include_router(router)
|
|
|
|
assert state.app_startup is False
|
|
assert state.router_startup is False
|
|
assert state.sub_router_startup is False
|
|
assert state.app_shutdown is False
|
|
assert state.router_shutdown is False
|
|
assert state.sub_router_shutdown is False
|
|
with TestClient(app) as client:
|
|
assert state.app_startup is True
|
|
assert state.router_startup is True
|
|
assert state.sub_router_startup is True
|
|
assert state.app_shutdown is False
|
|
assert state.router_shutdown is False
|
|
assert state.sub_router_shutdown is False
|
|
response = client.get("/")
|
|
assert response.status_code == 200, response.text
|
|
assert response.json() == {"message": "Hello World"}
|
|
assert state.app_startup is True
|
|
assert state.router_startup is True
|
|
assert state.sub_router_startup is True
|
|
assert state.app_shutdown is True
|
|
assert state.router_shutdown is True
|
|
assert state.sub_router_shutdown is True
|
|
|
|
|
|
def test_app_lifespan_state(state: State) -> None:
|
|
@asynccontextmanager
|
|
async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]:
|
|
state.app_startup = True
|
|
yield
|
|
state.app_shutdown = True
|
|
|
|
app = FastAPI(lifespan=lifespan)
|
|
|
|
@app.get("/")
|
|
def main() -> Dict[str, str]:
|
|
return {"message": "Hello World"}
|
|
|
|
assert state.app_startup is False
|
|
assert state.app_shutdown is False
|
|
with TestClient(app) as client:
|
|
assert state.app_startup is True
|
|
assert state.app_shutdown is False
|
|
response = client.get("/")
|
|
assert response.status_code == 200, response.text
|
|
assert response.json() == {"message": "Hello World"}
|
|
assert state.app_startup is True
|
|
assert state.app_shutdown is True
|