Skip to content

Commit 1c51e53

Browse files
authored
Merge pull request #76 from luolingchun/openapi_extra
Openapi extra
2 parents 035c127 + e3b928a commit 1c51e53

26 files changed

+860
-373
lines changed

.github/pull_request_template.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@ Checklist:
22

33
- [ ] Run `pytest tests` and no failed.
44
- [ ] Run `flake8 flask_openapi3 tests examples` and no failed.
5-
- [ ] Run `mkdocs serve` and no failed.
65
- [ ] Run `mypy flask_openapi3` and no failed.
6+
- [ ] Run `mkdocs serve` and no failed.

docs/Example.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,7 @@ class BookResponse(BaseModel):
127127
tags=[book_tag],
128128
summary='new summary',
129129
description='new description',
130-
responses={"200": BookResponse},
131-
extra_responses={"200": {"content": {"text/csv": {"schema": {"type": "string"}}}}},
130+
responses={"200": BookResponse, "201": {"content": {"text/csv": {"schema": {"type": "string"}}}}},
132131
security=security
133132
)
134133
def get_book(path: BookPath):
@@ -189,7 +188,6 @@ from typing import Optional
189188
from pydantic import BaseModel, Field
190189

191190
from flask_openapi3 import APIBlueprint, OpenAPI
192-
from flask_openapi3 import HTTPBearer
193191
from flask_openapi3 import Tag, Info
194192

195193
info = Info(title='book API', version='1.0.0')
@@ -238,7 +236,7 @@ def get_book():
238236
return {"code": 0, "message": "ok"}
239237

240238

241-
@api.post('/book', extra_responses={"200": {"content": {"text/csv": {"schema": {"type": "string"}}}}})
239+
@api.post('/book', responses={"201": {"content": {"text/csv": {"schema": {"type": "string"}}}}})
242240
def create_book(body: BookBody):
243241
assert body.age == 3
244242
return {"code": 0, "message": "ok"}

docs/Tutorial/Openapi_extra.md

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
*New in v2.4.0*
2+
3+
The [BaseModel](https://docs.pydantic.dev/latest/usage/models/) in [Pydantic](https://github.com/pydantic/pydantic)
4+
supports some custom configurations([Model Config](https://docs.pydantic.dev/latest/usage/model_config/)),
5+
so we can use the `openapi_extra` to extend OpenAPI Specification.
6+
7+
The `openapi_extra` will be merged with the automatically generated OpenAPI schema.
8+
9+
## form
10+
11+
```python
12+
class UploadFilesForm(BaseModel):
13+
file: FileStorage
14+
str_list: List[str]
15+
16+
class Config:
17+
openapi_extra = {
18+
# "example": {"a": 123},
19+
"examples": {
20+
"Example 01": {
21+
"summary": "An example",
22+
"value": {
23+
"file": "Example-01.jpg",
24+
"str_list": ["a", "b", "c"]
25+
}
26+
},
27+
"Example 02": {
28+
"summary": "Another example",
29+
"value": {
30+
"str_list": ["1", "2", "3"]
31+
}
32+
}
33+
}
34+
}
35+
```
36+
37+
Effect in Redoc:
38+
39+
![](../assets/Snipaste_2023-06-02_11-05-11.png)
40+
41+
## body
42+
43+
```python
44+
class BookBody(BaseModel):
45+
age: int
46+
author: str
47+
48+
class Config:
49+
openapi_extra = {
50+
"description": "This is post RequestBody",
51+
"example": {"age": 12, "author": "author1"},
52+
"examples": {
53+
"example1": {
54+
"summary": "example summary1",
55+
"description": "example description1",
56+
"value": {
57+
"age": 24,
58+
"author": "author2"
59+
}
60+
},
61+
"example2": {
62+
"summary": "example summary2",
63+
"description": "example description2",
64+
"value": {
65+
"age": 48,
66+
"author": "author3"
67+
}
68+
}
69+
70+
}}
71+
```
72+
73+
Effect in swagger:
74+
75+
![](../assets/Snipaste_2023-06-02_11-06-59.png)
76+
77+
## responses
78+
79+
```python
80+
class Message(BaseModel):
81+
message: str = Field(..., description="The message")
82+
83+
class Config:
84+
openapi_extra = {
85+
# "example": {"message": "aaa"},
86+
"examples": {
87+
"example1": {
88+
"summary": "example1 summary",
89+
"value": {
90+
"message": "bbb"
91+
}
92+
},
93+
"example2": {
94+
"summary": "example2 summary",
95+
"value": {
96+
"message": "ccc"
97+
}
98+
}
99+
}
100+
}
101+
```
102+
103+
Effect in swagger:
104+
105+
![](../assets/Snipaste_2023-06-02_11-08-40.png)

docs/Tutorial/Operation.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,12 @@ def create_book(body: BookBody):
127127

128128
## extra_form
129129

130+
*new in v2.4.0*
131+
132+
!!! Deprecated-Warning warning
133+
134+
`extra_form` will be deprecated in v3.x, please use `openapi_extra` instead.
135+
130136
*new in v2.1.0*
131137

132138
Extra form information can be provided using `extra_form` as in the following sample:
@@ -148,6 +154,12 @@ def create_book(body: BookForm):
148154

149155
## extra_body
150156

157+
*new in v2.4.0*
158+
159+
!!! Deprecated-Warning warning
160+
161+
`extra_body` will be deprecated in v3.x, please use `openapi_extra` instead.
162+
151163
*new in v2.1.0*
152164

153165
Extra body information can be provided using `extra_body` as in the following sample:

docs/Tutorial/Response.md

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,13 @@ class BookResponse(BaseModel):
1515
data: BookBodyWithID
1616

1717

18-
@app.get('/book/<int:bid>', tags=[book_tag], responses={"200": BookResponse})
18+
@app.get('/book/<int:bid>',
19+
tags=[book_tag],
20+
responses={
21+
"200": BookResponse,
22+
# Version 2.4.0 starts supporting response for dictionary types
23+
"201": {"content": {"text/csv": {"schema": {"type": "string"}}}}
24+
})
1925
def get_book(path: BookPath, query: BookBody):
2026
"""get a book
2127
get book by id, age or author
@@ -26,9 +32,14 @@ def get_book(path: BookPath, query: BookBody):
2632

2733
![image-20210526104627124](../assets/image-20210526104627124.png)
2834

29-
3035
## extra_responses
3136

37+
*New in v2.4.0*
38+
39+
!!! Deprecated-Warning warning
40+
41+
`extra_responses` have been merged into the `responses`, and `extra_responses` will be deprecated in v3.x.
42+
3243
*New in v1.0.0*
3344

3445
You can pass to your path operation decorators a parameter `extra_responses`.
@@ -43,14 +54,14 @@ Like this:
4354
'/book/<int:bid>',
4455
tags=[book_tag],
4556
responses={"200": BookResponse},
46-
extra_responses={"200": {"content": {"text/csv": {"schema": {"type": "string"}}}}},
57+
extra_responses={"201": {"content": {"text/csv": {"schema": {"type": "string"}}}}},
4758
security=security
4859
)
4960
def get_book(path: BookPath):
5061
...
5162

5263

53-
@api.post('/book', extra_responses={"200": {"content": {"text/csv": {"schema": {"type": "string"}}}}})
64+
@api.post('/book', extra_responses={"201": {"content": {"text/csv": {"schema": {"type": "string"}}}}})
5465
def create_book(body: BookBody):
5566
...
5667
```

docs/Tutorial/Specification.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,14 @@ def endpoint():
252252

253253
You can also use [responses ](./Response.md#responses) and [extra_responses](./Response.md#extra_responses) in your api.
254254

255+
*New in v2.4.0*
256+
257+
!!! Deprecated-Warning warning
258+
259+
`extra_responses` have been merged into the `responses`, and `extra_responses` will be deprecated in v3.x.
260+
261+
262+
255263
## doc_ui
256264

257265
You can pass `doc_ui=False` to disable the `OpenAPI spec` when init `OpenAPI `.
48.1 KB
Loading
28.8 KB
Loading
31.4 KB
Loading

examples/api_blueprint_demo.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ def get_book():
5555
return {"code": 0, "message": "ok"}
5656

5757

58-
@api.post('/book', extra_responses={"200": {"content": {"text/csv": {"schema": {"type": "string"}}}}})
58+
@api.post('/book', responses={"200": {"content": {"text/csv": {"schema": {"type": "string"}}}}})
5959
def create_book(body: BookBody):
6060
assert body.age == 3
6161
return {"code": 0, "message": "ok"}

0 commit comments

Comments
 (0)