Skip to content
This repository has been archived by the owner on May 25, 2023. It is now read-only.

Commit

Permalink
✨ Add additonal OpenAPI metadata parameters to FastAPI class, shown…
Browse files Browse the repository at this point in the history
… on the automatic API docs UI (fastapi#1812)

Co-authored-by: Marcelo Trylesinski <[email protected]>
Co-authored-by: dkreeft <[email protected]>
Co-authored-by: Sebastián Ramírez <[email protected]>
  • Loading branch information
4 people authored Jul 29, 2021
1 parent 6c80e9a commit 6f45f43
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 19 deletions.
Binary file modified docs/en/docs/img/tutorial/metadata/image01.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 15 additions & 8 deletions docs/en/docs/tutorial/metadata.md
Original file line number Diff line number Diff line change
Expand Up @@ -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">
Expand Down
33 changes: 29 additions & 4 deletions docs_src/metadata/tutorial001.py
Original file line number Diff line number Diff line change
@@ -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": "[email protected]",
},
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"}]
9 changes: 9 additions & 0 deletions fastapi/applications.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ def __init__(
] = 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,
Expand Down Expand Up @@ -97,6 +100,9 @@ def __init__(
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
Expand Down Expand Up @@ -132,6 +138,9 @@ def openapi(self) -> Dict[str, Any]:
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,
Expand Down
11 changes: 10 additions & 1 deletion fastapi/openapi/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
22 changes: 16 additions & 6 deletions tests/test_tutorial/test_metadata/test_tutorial001.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,31 @@
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": "[email protected]",
},
"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",
}
}
},
Expand All @@ -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"}]

0 comments on commit 6f45f43

Please sign in to comment.