]> git.ipfire.org Git - thirdparty/fastapi/fastapi.git/commitdiff
:sparkles: Allow docstrings to be truncated before being used for OpenAPI (#556)
authorsvalouch <54674660+svalouch@users.noreply.github.com>
Fri, 4 Oct 2019 20:02:40 +0000 (22:02 +0200)
committerSebastián Ramírez <tiangolo@gmail.com>
Fri, 4 Oct 2019 20:02:40 +0000 (15:02 -0500)
docs/src/path_operation_advanced_configuration/tutorial003.py [new file with mode: 0644]
docs/tutorial/path-operation-advanced-configuration.md
fastapi/routing.py
tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial003.py [new file with mode: 0644]

diff --git a/docs/src/path_operation_advanced_configuration/tutorial003.py b/docs/src/path_operation_advanced_configuration/tutorial003.py
new file mode 100644 (file)
index 0000000..36bf02b
--- /dev/null
@@ -0,0 +1,30 @@
+from typing import Set
+
+from fastapi import FastAPI
+from pydantic import BaseModel
+
+app = FastAPI()
+
+
+class Item(BaseModel):
+    name: str
+    description: str = None
+    price: float
+    tax: float = None
+    tags: Set[str] = []
+
+
+@app.post("/items/", response_model=Item, summary="Create an item")
+async def create_item(*, item: Item):
+    """
+    Create an item with all the information:
+
+    - **name**: each item must have a name
+    - **description**: a long description
+    - **price**: required
+    - **tax**: if the item doesn't have tax, you can omit this
+    - **tags**: a set of unique tag strings for this item
+    \f
+    :param item: User input.
+    """
+    return item
index 7d1b8e7349758922465c469dffd254de58595f36..b316159c5fae0ff2c56f2ca84651ff20350b4cf8 100644 (file)
@@ -18,3 +18,15 @@ To exclude a path operation from the generated OpenAPI schema (and thus, from th
 ```Python hl_lines="6"
 {!./src/path_operation_advanced_configuration/tutorial002.py!}
 ```
+
+## Advanced description from docstring
+
+You can limit the lines used from the docstring of a *path operation function* for OpenAPI.
+
+Adding an `\f` (an escaped "form feed" character) causes **FastAPI** to truncate the output used for OpenAPI at this point.
+
+It won't show up in the documentation, but other tools (such as Sphinx) will be able to use the rest.
+
+```Python hl_lines="19 20 21 22 23 24 25 26 27 28 29"
+{!./src/path_operation_advanced_configuration/tutorial003.py!}
+```
index aeafd07187e8111092f6096b901dd50a96cd1894..8f61ea50ca484aa86662bc41756fd5a6c12cd0e5 100644 (file)
@@ -246,6 +246,9 @@ class APIRoute(routing.Route):
             self.dependencies = []
         self.summary = summary
         self.description = description or inspect.cleandoc(self.endpoint.__doc__ or "")
+        # if a "form feed" character (page break) is found in the description text,
+        # truncate description text to the content preceding the first "form feed"
+        self.description = self.description.split("\f")[0]
         self.response_description = response_description
         self.responses = responses or {}
         response_fields = {}
diff --git a/tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial003.py b/tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial003.py
new file mode 100644 (file)
index 0000000..9fae316
--- /dev/null
@@ -0,0 +1,112 @@
+from starlette.testclient import TestClient
+
+from path_operation_advanced_configuration.tutorial003 import app
+
+client = TestClient(app)
+
+openapi_schema = {
+    "openapi": "3.0.2",
+    "info": {"title": "Fast API", "version": "0.1.0"},
+    "paths": {
+        "/items/": {
+            "post": {
+                "responses": {
+                    "200": {
+                        "description": "Successful Response",
+                        "content": {
+                            "application/json": {
+                                "schema": {"$ref": "#/components/schemas/Item"}
+                            }
+                        },
+                    },
+                    "422": {
+                        "description": "Validation Error",
+                        "content": {
+                            "application/json": {
+                                "schema": {
+                                    "$ref": "#/components/schemas/HTTPValidationError"
+                                }
+                            }
+                        },
+                    },
+                },
+                "summary": "Create an item",
+                "description": "Create an item with all the information:\n\n- **name**: each item must have a name\n- **description**: a long description\n- **price**: required\n- **tax**: if the item doesn't have tax, you can omit this\n- **tags**: a set of unique tag strings for this item\n",
+                "operationId": "create_item_items__post",
+                "requestBody": {
+                    "content": {
+                        "application/json": {
+                            "schema": {"$ref": "#/components/schemas/Item"}
+                        }
+                    },
+                    "required": True,
+                },
+            }
+        }
+    },
+    "components": {
+        "schemas": {
+            "Item": {
+                "title": "Item",
+                "required": ["name", "price"],
+                "type": "object",
+                "properties": {
+                    "name": {"title": "Name", "type": "string"},
+                    "price": {"title": "Price", "type": "number"},
+                    "description": {"title": "Description", "type": "string"},
+                    "tax": {"title": "Tax", "type": "number"},
+                    "tags": {
+                        "title": "Tags",
+                        "uniqueItems": True,
+                        "type": "array",
+                        "items": {"type": "string"},
+                        "default": [],
+                    },
+                },
+            },
+            "ValidationError": {
+                "title": "ValidationError",
+                "required": ["loc", "msg", "type"],
+                "type": "object",
+                "properties": {
+                    "loc": {
+                        "title": "Location",
+                        "type": "array",
+                        "items": {"type": "string"},
+                    },
+                    "msg": {"title": "Message", "type": "string"},
+                    "type": {"title": "Error Type", "type": "string"},
+                },
+            },
+            "HTTPValidationError": {
+                "title": "HTTPValidationError",
+                "type": "object",
+                "properties": {
+                    "detail": {
+                        "title": "Detail",
+                        "type": "array",
+                        "items": {"$ref": "#/components/schemas/ValidationError"},
+                    }
+                },
+            },
+        }
+    },
+}
+
+
+def test_openapi_schema():
+    response = client.get("/openapi.json")
+    assert response.status_code == 200
+    assert response.json() == openapi_schema
+
+
+def test_query_params_str_validations():
+    response = client.post("/items/", json={"name": "Foo", "price": 42})
+    assert response.status_code == 200
+    assert response.json() == {
+        "name": "Foo",
+        "price": 42,
+        "description": None,
+        "tax": None,
+        "tags": [],
+    }