From c8a99a62a4f8ba3a13ba44a8f4dccd9414ac62ca Mon Sep 17 00:00:00 2001 From: Yurii Motov Date: Wed, 26 Nov 2025 20:44:29 +0100 Subject: [PATCH] Add variants for `additional_responses/tutorial002` --- docs/en/docs/advanced/additional-responses.md | 2 +- .../additional_responses/tutorial002_py310.py | 28 +++++++++++++++++++ .../test_tutorial002.py | 27 ++++++++++++++---- 3 files changed, 50 insertions(+), 7 deletions(-) create mode 100644 docs_src/additional_responses/tutorial002_py310.py diff --git a/docs/en/docs/advanced/additional-responses.md b/docs/en/docs/advanced/additional-responses.md index 799532c5b..3422f59d6 100644 --- a/docs/en/docs/advanced/additional-responses.md +++ b/docs/en/docs/advanced/additional-responses.md @@ -175,7 +175,7 @@ You can use this same `responses` parameter to add different media types for the For example, you can add an additional media type of `image/png`, declaring that your *path operation* can return a JSON object (with media type `application/json`) or a PNG image: -{* ../../docs_src/additional_responses/tutorial002.py hl[19:24,28] *} +{* ../../docs_src/additional_responses/tutorial002_py310.py hl[17:22,26] *} /// note diff --git a/docs_src/additional_responses/tutorial002_py310.py b/docs_src/additional_responses/tutorial002_py310.py new file mode 100644 index 000000000..a94b740c9 --- /dev/null +++ b/docs_src/additional_responses/tutorial002_py310.py @@ -0,0 +1,28 @@ +from fastapi import FastAPI +from fastapi.responses import FileResponse +from pydantic import BaseModel + + +class Item(BaseModel): + id: str + value: str + + +app = FastAPI() + + +@app.get( + "/items/{item_id}", + response_model=Item, + responses={ + 200: { + "content": {"image/png": {}}, + "description": "Return the JSON item or an image.", + } + }, +) +async def read_item(item_id: str, img: bool | None = None): + if img: + return FileResponse("image.png", media_type="image/png") + else: + return {"id": "foo", "value": "there goes my hero"} diff --git a/tests/test_tutorial/test_additional_responses/test_tutorial002.py b/tests/test_tutorial/test_additional_responses/test_tutorial002.py index 588a3160a..91d6ff101 100644 --- a/tests/test_tutorial/test_additional_responses/test_tutorial002.py +++ b/tests/test_tutorial/test_additional_responses/test_tutorial002.py @@ -1,21 +1,36 @@ +import importlib import os import shutil +import pytest from dirty_equals import IsDict from fastapi.testclient import TestClient -from docs_src.additional_responses.tutorial002 import app - -client = TestClient(app) +from tests.utils import needs_py310 -def test_path_operation(): +@pytest.fixture( + name="client", + params=[ + pytest.param("tutorial002"), + pytest.param("tutorial002_py310", marks=needs_py310), + ], +) +def get_client(request: pytest.FixtureRequest): + mod = importlib.import_module(f"docs_src.additional_responses.{request.param}") + + client = TestClient(mod.app) + client.headers.clear() + return client + + +def test_path_operation(client: TestClient): response = client.get("/items/foo") assert response.status_code == 200, response.text assert response.json() == {"id": "foo", "value": "there goes my hero"} -def test_path_operation_img(): +def test_path_operation_img(client: TestClient): shutil.copy("./docs/en/docs/img/favicon.png", "./image.png") response = client.get("/items/foo?img=1") assert response.status_code == 200, response.text @@ -24,7 +39,7 @@ def test_path_operation_img(): os.remove("./image.png") -def test_openapi_schema(): +def test_openapi_schema(client: TestClient): response = client.get("/openapi.json") assert response.status_code == 200, response.text assert response.json() == {