Skip to content

Commit 7dad5a8

Browse files
authored
✨ Add support for OpenAPI 3.1.0 (#9770)
* ✨ Update OpenAPI models for JSON Schema 2020-12 and OpenAPI 3.1.0 * ✨ Add support for summary and webhooks * ✨ Update JSON Schema for UploadFiles * ⏪️ Revert making paths optional, to ensure always correctness * ⏪️ Keep UploadFile as format: binary for compatibility with the rest of Pydantic bytes fields in v1 * ✨ Update version of OpenAPI generated to 3.1.0 * ✨ Update the version of Swagger UI * 📝 Update docs about extending OpenAPI * 📝 Update docs and links to refer to OpenAPI 3.1.0 * ✨ Update logic for handling webhooks * ♻️ Update parameter functions and classes, deprecate example and make examples the main field * ✅ Update tests for OpenAPI 3.1.0 * 📝 Update examples for OpenAPI metadata * ✅ Add and update tests for OpenAPI metadata * 📝 Add source example for webhooks * 📝 Update docs for metadata * 📝 Update docs for Schema extra * 📝 Add docs for webhooks * 🔧 Add webhooks docs to MkDocs * ✅ Update tests for extending OpenAPI * ✅ Add tests for webhooks * ♻️ Refactor generation of OpenAPI and JSON Schema with params * 📝 Update source examples for field examples * ✅ Update tests for examples * ➕ Make sure the minimum version of typing-extensions installed has deprecated() (already a dependency of Pydantic) * ✏️ Fix typo in Webhooks example code * 🔥 Remove commented out code of removed nullable field * 🗑️ Add deprecation warnings for example argument * ✅ Update tests to check for deprecation warnings * ✅ Add test for webhooks with security schemes, for coverage * 🍱 Update image for metadata, with new summary * 🍱 Add docs image for Webhooks * 📝 Update docs for webhooks, add docs UI image
1 parent 02fc9e8 commit 7dad5a8

File tree

335 files changed

+1564
-922
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

335 files changed

+1564
-922
lines changed

docs/en/docs/advanced/additional-responses.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -236,5 +236,5 @@ For example:
236236

237237
To see what exactly you can include in the responses, you can check these sections in the OpenAPI specification:
238238

239-
* <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#responsesObject" class="external-link" target="_blank">OpenAPI Responses Object</a>, it includes the `Response Object`.
240-
* <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#responseObject" class="external-link" target="_blank">OpenAPI Response Object</a>, you can include anything from this directly in each response inside your `responses` parameter. Including `description`, `headers`, `content` (inside of this is that you declare different media types and JSON Schemas), and `links`.
239+
* <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#responsesObject" class="external-link" target="_blank">OpenAPI Responses Object</a>, it includes the `Response Object`.
240+
* <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#responseObject" class="external-link" target="_blank">OpenAPI Response Object</a>, you can include anything from this directly in each response inside your `responses` parameter. Including `description`, `headers`, `content` (inside of this is that you declare different media types and JSON Schemas), and `links`.

docs/en/docs/advanced/behind-a-proxy.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ The docs UI would also need the OpenAPI schema to declare that this API `server`
4646

4747
```JSON hl_lines="4-8"
4848
{
49-
"openapi": "3.0.2",
49+
"openapi": "3.1.0",
5050
// More stuff here
5151
"servers": [
5252
{
@@ -298,7 +298,7 @@ Will generate an OpenAPI schema like:
298298

299299
```JSON hl_lines="5-7"
300300
{
301-
"openapi": "3.0.2",
301+
"openapi": "3.1.0",
302302
// More stuff here
303303
"servers": [
304304
{

docs/en/docs/advanced/extending-openapi.md

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,14 @@ And that function `get_openapi()` receives as parameters:
2929

3030
* `title`: The OpenAPI title, shown in the docs.
3131
* `version`: The version of your API, e.g. `2.5.0`.
32-
* `openapi_version`: The version of the OpenAPI specification used. By default, the latest: `3.0.2`.
33-
* `description`: The description of your API.
32+
* `openapi_version`: The version of the OpenAPI specification used. By default, the latest: `3.1.0`.
33+
* `summary`: A short summary of the API.
34+
* `description`: The description of your API, this can include markdown and will be shown in the docs.
3435
* `routes`: A list of routes, these are each of the registered *path operations*. They are taken from `app.routes`.
3536

37+
!!! info
38+
The parameter `summary` is available in OpenAPI 3.1.0 and above, supported by FastAPI 0.99.0 and above.
39+
3640
## Overriding the defaults
3741

3842
Using the information above, you can use the same utility function to generate the OpenAPI schema and override each part that you need.
@@ -51,15 +55,15 @@ First, write all your **FastAPI** application as normally:
5155

5256
Then, use the same utility function to generate the OpenAPI schema, inside a `custom_openapi()` function:
5357

54-
```Python hl_lines="2 15-20"
58+
```Python hl_lines="2 15-21"
5559
{!../../../docs_src/extending_openapi/tutorial001.py!}
5660
```
5761

5862
### Modify the OpenAPI schema
5963

6064
Now you can add the ReDoc extension, adding a custom `x-logo` to the `info` "object" in the OpenAPI schema:
6165

62-
```Python hl_lines="21-23"
66+
```Python hl_lines="22-24"
6367
{!../../../docs_src/extending_openapi/tutorial001.py!}
6468
```
6569

@@ -71,15 +75,15 @@ That way, your application won't have to generate the schema every time a user o
7175

7276
It will be generated only once, and then the same cached schema will be used for the next requests.
7377

74-
```Python hl_lines="13-14 24-25"
78+
```Python hl_lines="13-14 25-26"
7579
{!../../../docs_src/extending_openapi/tutorial001.py!}
7680
```
7781

7882
### Override the method
7983

8084
Now you can replace the `.openapi()` method with your new function.
8185

82-
```Python hl_lines="28"
86+
```Python hl_lines="29"
8387
{!../../../docs_src/extending_openapi/tutorial001.py!}
8488
```
8589

docs/en/docs/advanced/openapi-callbacks.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,11 @@ It should look just like a normal FastAPI *path operation*:
103103
There are 2 main differences from a normal *path operation*:
104104

105105
* It doesn't need to have any actual code, because your app will never call this code. It's only used to document the *external API*. So, the function could just have `pass`.
106-
* The *path* can contain an <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#key-expression" class="external-link" target="_blank">OpenAPI 3 expression</a> (see more below) where it can use variables with parameters and parts of the original request sent to *your API*.
106+
* The *path* can contain an <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression" class="external-link" target="_blank">OpenAPI 3 expression</a> (see more below) where it can use variables with parameters and parts of the original request sent to *your API*.
107107

108108
### The callback path expression
109109

110-
The callback *path* can have an <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#key-expression" class="external-link" target="_blank">OpenAPI 3 expression</a> that can contain parts of the original request sent to *your API*.
110+
The callback *path* can have an <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression" class="external-link" target="_blank">OpenAPI 3 expression</a> that can contain parts of the original request sent to *your API*.
111111

112112
In this case, it's the `str`:
113113

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# OpenAPI Webhooks
2+
3+
There are cases where you want to tell your API **users** that your app could call *their* app (sending a request) with some data, normally to **notify** of some type of **event**.
4+
5+
This means that instead of the normal process of your users sending requests to your API, it's **your API** (or your app) that could **send requests to their system** (to their API, their app).
6+
7+
This is normally called a **webhook**.
8+
9+
## Webhooks steps
10+
11+
The process normally is that **you define** in your code what is the message that you will send, the **body of the request**.
12+
13+
You also define in some way at which **moments** your app will send those requests or events.
14+
15+
And **your users** define in some way (for example in a web dashboard somewhere) the **URL** where your app should send those requests.
16+
17+
All the **logic** about how to register the URLs for webhooks and the code to actually send those requests is up to you. You write it however you want to in **your own code**.
18+
19+
## Documenting webhooks with **FastAPI** and OpenAPI
20+
21+
With **FastAPI**, using OpenAPI, you can define the names of these webhooks, the types of HTTP operations that your app can send (e.g. `POST`, `PUT`, etc.) and the request **bodies** that your app would send.
22+
23+
This can make it a lot easier for your users to **implement their APIs** to receive your **webhook** requests, they might even be able to autogenerate some of their own API code.
24+
25+
!!! info
26+
Webhooks are available in OpenAPI 3.1.0 and above, supported by FastAPI `0.99.0` and above.
27+
28+
## An app with webhooks
29+
30+
When you create a **FastAPI** application, there is a `webhooks` attribute that you can use to define *webhooks*, the same way you would define *path operations*, for example with `@app.webhooks.post()`.
31+
32+
```Python hl_lines="9-13 36-53"
33+
{!../../../docs_src/openapi_webhooks/tutorial001.py!}
34+
```
35+
36+
The webhooks that you define will end up in the **OpenAPI** schema and the automatic **docs UI**.
37+
38+
!!! info
39+
The `app.webhooks` object is actually just an `APIRouter`, the same type you would use when structuring your app with multiple files.
40+
41+
Notice that with webhooks you are actually not declaring a *path* (like `/items/`), the text you pass there is just an **identifier** of the webhook (the name of the event), for example in `@app.webhooks.post("new-subscription")`, the webhook name is `new-subscription`.
42+
43+
This is because it is expected that **your users** would define the actual **URL path** where they want to receive the webhook request in some other way (e.g. a web dashboard).
44+
45+
### Check the docs
46+
47+
Now you can start your app with Uvicorn and go to <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>.
48+
49+
You will see your docs have the normal *path operations* and now also some **webhooks**:
50+
51+
<img src="/img/tutorial/openapi-webhooks/image01.png">

docs/en/docs/advanced/path-operation-advanced-configuration.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ And if you see the resulting OpenAPI (at `/openapi.json` in your API), you will
9797

9898
```JSON hl_lines="22"
9999
{
100-
"openapi": "3.0.2",
100+
"openapi": "3.1.0",
101101
"info": {
102102
"title": "FastAPI",
103103
"version": "0.1.0"
-3.54 KB
Loading
Loading

docs/en/docs/tutorial/first-steps.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ It will show a JSON starting with something like:
9999

100100
```JSON
101101
{
102-
"openapi": "3.0.2",
102+
"openapi": "3.1.0",
103103
"info": {
104104
"title": "FastAPI",
105105
"version": "0.1.0"

docs/en/docs/tutorial/metadata.md

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,16 @@ You can set the following fields that are used in the OpenAPI specification and
99
| Parameter | Type | Description |
1010
|------------|------|-------------|
1111
| `title` | `str` | The title of the API. |
12+
| `summary` | `str` | A short summary of the API. <small>Available since OpenAPI 3.1.0, FastAPI 0.99.0.</small> |
1213
| `description` | `str` | A short description of the API. It can use Markdown. |
1314
| `version` | `string` | The version of the API. This is the version of your own application, not of OpenAPI. For example `2.5.0`. |
1415
| `terms_of_service` | `str` | A URL to the Terms of Service for the API. If provided, this has to be a URL. |
1516
| `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> |
16-
| `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> |
17+
| `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>identifier</code></td><td><code>str</code></td><td>An <a href="https://spdx.dev/spdx-specification-21-web-version/#h.jxpfx0ykyb60" class="external-link" target="_blank">SPDX</a> license expression for the API. The <code>identifier</code> field is mutually exclusive of the <code>url</code> field. <small>Available since OpenAPI 3.1.0, FastAPI 0.99.0.</small></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> |
1718

1819
You can set them as follows:
1920

20-
```Python hl_lines="3-16 19-31"
21+
```Python hl_lines="3-16 19-32"
2122
{!../../../docs_src/metadata/tutorial001.py!}
2223
```
2324

@@ -28,6 +29,16 @@ With this configuration, the automatic API docs would look like:
2829

2930
<img src="/img/tutorial/metadata/image01.png">
3031

32+
## License identifier
33+
34+
Since OpenAPI 3.1.0 and FastAPI 0.99.0, you can also set the `license_info` with an `identifier` instead of a `url`.
35+
36+
For example:
37+
38+
```Python hl_lines="31"
39+
{!../../../docs_src/metadata/tutorial001_1.py!}
40+
```
41+
3142
## Metadata for tags
3243

3344
You can also add additional metadata for the different tags used to group your path operations with the parameter `openapi_tags`.

0 commit comments

Comments
 (0)