]> git.ipfire.org Git - thirdparty/fastapi/fastapi.git/commitdiff
✨ Add additonal OpenAPI metadata parameters to `FastAPI` class, shown on the automati...
authordkreeft <37153972+dkreeft@users.noreply.github.com>
Thu, 29 Jul 2021 15:10:22 +0000 (15:10 +0000)
committerGitHub <noreply@github.com>
Thu, 29 Jul 2021 15:10:22 +0000 (17:10 +0200)
Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com>
Co-authored-by: dkreeft <dkreeft@xccelerated.io>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
docs/en/docs/img/tutorial/metadata/image01.png
docs/en/docs/tutorial/metadata.md
docs_src/metadata/tutorial001.py
fastapi/applications.py
fastapi/openapi/utils.py
tests/test_tutorial/test_metadata/test_tutorial001.py

index e9800d532f072ddda5e99a23e5449dd1cabd5e68..b7708a3fd98ad2170d880781896623ec8ed80204 100644 (file)
Binary files a/docs/en/docs/img/tutorial/metadata/image01.png and b/docs/en/docs/img/tutorial/metadata/image01.png differ
index 7ec3054218a161c183292868e72e40a4cd5fc159..78f17031a1566c084423faf89e996fd51a547869 100644 (file)
@@ -2,21 +2,28 @@
 
 You can customize several metadata configurations in your **FastAPI** application.
 
-## Title, description, and version
+## Metadata for API
 
-You can set the:
+You can set the following fields that are used in the OpenAPI specification and the automatic API docs UIs:
 
-* **Title**: used as your API's title/name, in OpenAPI and the automatic API docs UIs.
-* **Description**: the description of your API, in OpenAPI and the automatic API docs UIs.
-* **Version**: the version of your API, e.g. `v2` or `2.5.0`.
-    * Useful for example if you had a previous version of the application, also using OpenAPI.
+| Parameter | Type | Description |
+|------------|------|-------------|
+| `title` | `str` | The title of the API. |
+| `description` | `str` | A short description of the API. It can use Markdown. |
+| `version` | `string` | The version of the API. This is the version of your own application, not of OpenAPI. For example `2.5.0`. |
+| `terms_of_service` | `str` | A URL to the Terms of Service for the API. If provided, this has to be a URL. |
+| `contact` | `dict` | The contact information for the exposed API. It can contain several fields. <details><summary><code>contact</code> fields</summary><table><thead><tr><th>Parameter</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><code>name</code></td><td><code>str</code></td><td>The identifying name of the contact person/organization.</td></tr><tr><td><code>url</code></td><td><code>str</code></td><td>The URL pointing to the contact information. MUST be in the format of a URL.</td></tr><tr><td><code>email</code></td><td><code>str</code></td><td>The email address of the contact person/organization. MUST be in the format of an email address.</td></tr></tbody></table></details> |
+| `license_info` | `dict` | The license information for the exposed API. It can contain several fields. <details><summary><code>license_info</code> fields</summary><table><thead><tr><th>Parameter</th><th>Type</th><th>Description</th></tr></thead><tbody><tr><td><code>name</code></td><td><code>str</code></td><td><strong>REQUIRED</strong> (if a <code>license_info</code> is set). The license name used for the API.</td></tr><tr><td><code>url</code></td><td><code>str</code></td><td>A URL to the license used for the API. MUST be in the format of a URL.</td></tr></tbody></table></details> |
 
-To set them, use the parameters `title`, `description`, and `version`:
+You can set them as follows:
 
-```Python hl_lines="4-6"
+```Python hl_lines="3-16  19-31"
 {!../../../docs_src/metadata/tutorial001.py!}
 ```
 
+!!! tip
+    You can write Markdown in the `description` field and it will be rendered in the output.
+
 With this configuration, the automatic API docs would look like:
 
 <img src="/img/tutorial/metadata/image01.png">
index 16bab8a0c0c6b8c19b3b4f6e500c6b7514bac4ca..3fba9e7d1b272291157cc091229f954373cc1109 100644 (file)
@@ -1,12 +1,37 @@
 from fastapi import FastAPI
 
+description = """
+ChimichangApp API helps you do awesome stuff. 🚀
+
+## Items
+
+You can **read items**.
+
+## Users
+
+You will be able to:
+
+* **Create users** (_not implemented_).
+* **Read users** (_not implemented_).
+"""
+
 app = FastAPI(
-    title="My Super Project",
-    description="This is a very fancy project, with auto docs for the API and everything",
-    version="2.5.0",
+    title="ChimichangApp",
+    description=description,
+    version="0.0.1",
+    terms_of_service="http://example.com/terms/",
+    contact={
+        "name": "Deadpoolio the Amazing",
+        "url": "http://x-force.example.com/contact/",
+        "email": "dp@x-force.example.com",
+    },
+    license_info={
+        "name": "Apache 2.0",
+        "url": "https://www.apache.org/licenses/LICENSE-2.0.html",
+    },
 )
 
 
 @app.get("/items/")
 async def read_items():
-    return [{"name": "Foo"}]
+    return [{"name": "Katana"}]
index 3f78238d60f2fee84287f978d1fad1e5c0ca16df..b013e7b46a05f6786a4b6b936dd4eddf6843f56f 100644 (file)
@@ -55,6 +55,9 @@ class FastAPI(Starlette):
         ] = None,
         on_startup: Optional[Sequence[Callable[[], Any]]] = None,
         on_shutdown: Optional[Sequence[Callable[[], Any]]] = None,
+        terms_of_service: Optional[str] = None,
+        contact: Optional[Dict[str, Union[str, Any]]] = None,
+        license_info: Optional[Dict[str, Union[str, Any]]] = None,
         openapi_prefix: str = "",
         root_path: str = "",
         root_path_in_servers: bool = True,
@@ -97,6 +100,9 @@ class FastAPI(Starlette):
         self.title = title
         self.description = description
         self.version = version
+        self.terms_of_service = terms_of_service
+        self.contact = contact
+        self.license_info = license_info
         self.servers = servers or []
         self.openapi_url = openapi_url
         self.openapi_tags = openapi_tags
@@ -132,6 +138,9 @@ class FastAPI(Starlette):
                 version=self.version,
                 openapi_version=self.openapi_version,
                 description=self.description,
+                terms_of_service=self.terms_of_service,
+                contact=self.contact,
+                license_info=self.license_info,
                 routes=self.routes,
                 tags=self.openapi_tags,
                 servers=self.servers,
index 8dbe3902b10130ec0737cd4c4a2f089d90de3f63..604ba5b0060e0336d9699858a8b18df7b143415f 100644 (file)
@@ -362,10 +362,19 @@ def get_openapi(
     routes: Sequence[BaseRoute],
     tags: Optional[List[Dict[str, Any]]] = None,
     servers: Optional[List[Dict[str, Union[str, Any]]]] = None,
+    terms_of_service: Optional[str] = None,
+    contact: Optional[Dict[str, Union[str, Any]]] = None,
+    license_info: Optional[Dict[str, Union[str, Any]]] = None,
 ) -> Dict[str, Any]:
-    info = {"title": title, "version": version}
+    info: Dict[str, Any] = {"title": title, "version": version}
     if description:
         info["description"] = description
+    if terms_of_service:
+        info["termsOfService"] = terms_of_service
+    if contact:
+        info["contact"] = contact
+    if license_info:
+        info["license"] = license_info
     output: Dict[str, Any] = {"openapi": openapi_version, "info": info}
     if servers:
         output["servers"] = servers
index aae79dcc4c69b1aaf30ee4f0ae6904c3ddabfb51..b7281e29350a6de151394dc8236e741588de1ea5 100644 (file)
@@ -7,21 +7,31 @@ client = TestClient(app)
 openapi_schema = {
     "openapi": "3.0.2",
     "info": {
-        "title": "My Super Project",
-        "version": "2.5.0",
-        "description": "This is a very fancy project, with auto docs for the API and everything",
+        "title": "ChimichangApp",
+        "description": "\nChimichangApp API helps you do awesome stuff. 🚀\n\n## Items\n\nYou can **read items**.\n\n## Users\n\nYou will be able to:\n\n* **Create users** (_not implemented_).\n* **Read users** (_not implemented_).\n",
+        "termsOfService": "http://example.com/terms/",
+        "contact": {
+            "name": "Deadpoolio the Amazing",
+            "url": "http://x-force.example.com/contact/",
+            "email": "dp@x-force.example.com",
+        },
+        "license": {
+            "name": "Apache 2.0",
+            "url": "https://www.apache.org/licenses/LICENSE-2.0.html",
+        },
+        "version": "0.0.1",
     },
     "paths": {
         "/items/": {
             "get": {
+                "summary": "Read Items",
+                "operationId": "read_items_items__get",
                 "responses": {
                     "200": {
                         "description": "Successful Response",
                         "content": {"application/json": {"schema": {}}},
                     }
                 },
-                "summary": "Read Items",
-                "operationId": "read_items_items__get",
             }
         }
     },
@@ -37,4 +47,4 @@ def test_openapi_schema():
 def test_items():
     response = client.get("/items/")
     assert response.status_code == 200, response.text
-    assert response.json() == [{"name": "Foo"}]
+    assert response.json() == [{"name": "Katana"}]