From 449c18e67eb455d54b2ef320d75e1a846f48bb4c Mon Sep 17 00:00:00 2001 From: Yurii Motov Date: Thu, 27 Nov 2025 09:34:15 +0100 Subject: [PATCH] Add variants for `path-operation-advanced-configuration/tutorial007_pv1` --- .../path-operation-advanced-configuration.md | 4 +-- .../tutorial007_pv1_py39.py | 32 +++++++++++++++++++ .../test_tutorial007_pv1.py | 20 +++++++++--- 3 files changed, 49 insertions(+), 7 deletions(-) create mode 100644 docs_src/path_operation_advanced_configuration/tutorial007_pv1_py39.py diff --git a/docs/en/docs/advanced/path-operation-advanced-configuration.md b/docs/en/docs/advanced/path-operation-advanced-configuration.md index a28b8a35d..f88beefc4 100644 --- a/docs/en/docs/advanced/path-operation-advanced-configuration.md +++ b/docs/en/docs/advanced/path-operation-advanced-configuration.md @@ -161,7 +161,7 @@ For example, in this application we don't use FastAPI's integrated functionality //// tab | Pydantic v1 -{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1.py hl[17:22, 24] *} +{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1_py39.py hl[15:20, 22] *} //// @@ -185,7 +185,7 @@ And then in our code, we parse that YAML content directly, and then we are again //// tab | Pydantic v1 -{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1.py hl[26:33] *} +{* ../../docs_src/path_operation_advanced_configuration/tutorial007_pv1_py39.py hl[24:31] *} //// diff --git a/docs_src/path_operation_advanced_configuration/tutorial007_pv1_py39.py b/docs_src/path_operation_advanced_configuration/tutorial007_pv1_py39.py new file mode 100644 index 000000000..831966553 --- /dev/null +++ b/docs_src/path_operation_advanced_configuration/tutorial007_pv1_py39.py @@ -0,0 +1,32 @@ +import yaml +from fastapi import FastAPI, HTTPException, Request +from pydantic import BaseModel, ValidationError + +app = FastAPI() + + +class Item(BaseModel): + name: str + tags: list[str] + + +@app.post( + "/items/", + openapi_extra={ + "requestBody": { + "content": {"application/x-yaml": {"schema": Item.schema()}}, + "required": True, + }, + }, +) +async def create_item(request: Request): + raw_body = await request.body() + try: + data = yaml.safe_load(raw_body) + except yaml.YAMLError: + raise HTTPException(status_code=422, detail="Invalid YAML") + try: + item = Item.parse_obj(data) + except ValidationError as e: + raise HTTPException(status_code=422, detail=e.errors()) + return item diff --git a/tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial007_pv1.py b/tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial007_pv1.py index ef012f8a6..b38e4947c 100644 --- a/tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial007_pv1.py +++ b/tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial007_pv1.py @@ -1,14 +1,24 @@ +import importlib + import pytest from fastapi.testclient import TestClient -from ...utils import needs_pydanticv1 +from ...utils import needs_py39, needs_pydanticv1 -@pytest.fixture(name="client") -def get_client(): - from docs_src.path_operation_advanced_configuration.tutorial007_pv1 import app +@pytest.fixture( + name="client", + params=[ + pytest.param("tutorial007_pv1"), + pytest.param("tutorial007_pv1_py39", marks=needs_py39), + ], +) +def get_client(request: pytest.FixtureRequest): + mod = importlib.import_module( + f"docs_src.path_operation_advanced_configuration.{request.param}" + ) - client = TestClient(app) + client = TestClient(mod.app) return client