Skip to content

Commit 736dff7

Browse files
committed
Add docs
1 parent cd568ea commit 736dff7

File tree

9 files changed

+234
-4
lines changed

9 files changed

+234
-4
lines changed

docs/Usage/Request.md

Lines changed: 83 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,88 @@ def get_book(query: BookQuery, client_id:str = None):
167167
...
168168
```
169169

170+
## Multiple content types in the request body
171+
172+
```python
173+
from typing import Union
174+
175+
from flask import Request
176+
from pydantic import BaseModel
177+
178+
from flask_openapi3 import OpenAPI
179+
180+
app = OpenAPI(__name__)
181+
182+
183+
class DogBody(BaseModel):
184+
a: int = None
185+
b: str = None
186+
187+
model_config = {
188+
"openapi_extra": {
189+
"content_type": "application/vnd.dog+json"
190+
}
191+
}
192+
193+
194+
class CatBody(BaseModel):
195+
c: int = None
196+
d: str = None
197+
198+
model_config = {
199+
"openapi_extra": {
200+
"content_type": "application/vnd.cat+json"
201+
}
202+
}
203+
204+
205+
class BsonModel(BaseModel):
206+
e: int = None
207+
f: str = None
208+
209+
model_config = {
210+
"openapi_extra": {
211+
"content_type": "application/bson"
212+
}
213+
}
214+
215+
216+
class ContentTypeModel(BaseModel):
217+
model_config = {
218+
"openapi_extra": {
219+
"content_type": "text/csv"
220+
}
221+
}
222+
223+
224+
@app.post("/a", responses={200: DogBody | CatBody | ContentTypeModel | BsonModel})
225+
def index_a(body: DogBody | CatBody | ContentTypeModel | BsonModel):
226+
"""
227+
multiple content types examples.
228+
229+
This may be confusing, if the content-type is application/json, the type of body will be auto parsed to
230+
DogBody or CatBody, otherwise it cannot be parsed to ContentTypeModel or BsonModel.
231+
The body is equivalent to the request variable in Flask, and you can use body.data, body.text, etc ...
232+
"""
233+
print(body)
234+
if isinstance(body, Request):
235+
if body.mimetype == "text/csv":
236+
# processing csv data
237+
...
238+
elif body.mimetype == "application/bson":
239+
# processing bson data
240+
...
241+
else:
242+
# DogBody or CatBody
243+
...
244+
return {"hello": "world"}
245+
```
246+
247+
The effect in swagger:
248+
249+
![](../assets/Snipaste_2025-01-14_10-44-00.png)
250+
251+
170252
## Request model
171253

172254
First, you need to define a [pydantic](https://github.com/pydantic/pydantic) model:
@@ -191,7 +273,7 @@ class BookQuery(BaseModel):
191273
author: str = Field(None, description='Author', json_schema_extra={"deprecated": True})
192274
```
193275

194-
Magic:
276+
The effect in swagger:
195277

196278
![](../assets/Snipaste_2022-09-04_10-10-03.png)
197279

docs/Usage/Response.md

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,122 @@ def hello(path: HelloPath):
5656

5757
![image-20210526104627124](../assets/image-20210526104627124.png)
5858

59+
*Sometimes you may need more description fields about the response, such as description, headers and links.
60+
61+
You can use the following form:
62+
63+
```python
64+
@app.get(
65+
"/test",
66+
responses={
67+
"201": {
68+
"model": BaseResponse,
69+
"description": "Custom description",
70+
"headers": {
71+
"location": {
72+
"description": "URL of the new resource",
73+
"schema": {"type": "string"}
74+
}
75+
},
76+
"links": {
77+
"dummy": {
78+
"description": "dummy link"
79+
}
80+
}
81+
}
82+
}
83+
)
84+
def endpoint_test():
85+
...
86+
```
87+
88+
The effect in swagger:
89+
90+
![](../assets/Snipaste_2025-01-14_11-08-40.png)
91+
92+
93+
## Multiple content types in the responses
94+
95+
```python
96+
from typing import Union
97+
98+
from flask import Request
99+
from pydantic import BaseModel
100+
101+
from flask_openapi3 import OpenAPI
102+
103+
app = OpenAPI(__name__)
104+
105+
106+
class DogBody(BaseModel):
107+
a: int = None
108+
b: str = None
109+
110+
model_config = {
111+
"openapi_extra": {
112+
"content_type": "application/vnd.dog+json"
113+
}
114+
}
115+
116+
117+
class CatBody(BaseModel):
118+
c: int = None
119+
d: str = None
120+
121+
model_config = {
122+
"openapi_extra": {
123+
"content_type": "application/vnd.cat+json"
124+
}
125+
}
126+
127+
128+
class BsonModel(BaseModel):
129+
e: int = None
130+
f: str = None
131+
132+
model_config = {
133+
"openapi_extra": {
134+
"content_type": "application/bson"
135+
}
136+
}
137+
138+
139+
class ContentTypeModel(BaseModel):
140+
model_config = {
141+
"openapi_extra": {
142+
"content_type": "text/csv"
143+
}
144+
}
145+
146+
147+
@app.post("/a", responses={200: DogBody | CatBody | ContentTypeModel | BsonModel})
148+
def index_a(body: DogBody | CatBody | ContentTypeModel | BsonModel):
149+
"""
150+
multiple content types examples.
151+
152+
This may be confusing, if the content-type is application/json, the type of body will be auto parsed to
153+
DogBody or CatBody, otherwise it cannot be parsed to ContentTypeModel or BsonModel.
154+
The body is equivalent to the request variable in Flask, and you can use body.data, body.text, etc ...
155+
"""
156+
print(body)
157+
if isinstance(body, Request):
158+
if body.mimetype == "text/csv":
159+
# processing csv data
160+
...
161+
elif body.mimetype == "application/bson":
162+
# processing bson data
163+
...
164+
else:
165+
# DogBody or CatBody
166+
...
167+
return {"hello": "world"}
168+
```
169+
170+
The effect in swagger:
171+
172+
![](../assets/Snipaste_2025-01-14_10-49-19.png)
173+
174+
59175
## More information about OpenAPI responses
60176

61177
- [OpenAPI Responses Object](https://spec.openapis.org/oas/v3.1.0#responses-object), it includes the Response Object.

docs/Usage/Route_Operation.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,29 @@ class BookListAPIView:
289289
app.register_api_view(api_view)
290290
```
291291

292+
## request_body_description
293+
294+
A brief description of the request body.
295+
296+
```python
297+
from flask_openapi3 import OpenAPI
298+
299+
app = OpenAPI(__name__)
300+
301+
@app.post(
302+
"/",
303+
request_body_description="A brief description of the request body."
304+
)
305+
def create_book(body: Bookbody):
306+
...
307+
```
308+
309+
![](../assets/Snipaste_2025-01-14_10-56-40.png)
310+
311+
## request_body_required
312+
313+
Determines if the request body is required in the request.
314+
292315
## doc_ui
293316

294317
You can pass `doc_ui=False` to disable the `OpenAPI spec` when init `OpenAPI `.
18.1 KB
Loading
19.4 KB
Loading
7.53 KB
Loading
18 KB
Loading

examples/multi_content_type.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ class ContentTypeModel(BaseModel):
5353
@app.post("/a", responses={200: DogBody | CatBody | ContentTypeModel | BsonModel})
5454
def index_a(body: DogBody | CatBody | ContentTypeModel | BsonModel):
5555
"""
56+
multiple content types examples.
57+
5658
This may be confusing, if the content-type is application/json, the type of body will be auto parsed to
5759
DogBody or CatBody, otherwise it cannot be parsed to ContentTypeModel or BsonModel.
5860
The body is equivalent to the request variable in Flask, and you can use body.data, body.text, etc ...

flask_openapi3/utils.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,16 @@
77
import sys
88
from enum import Enum
99
from http import HTTPStatus
10-
from typing import Any, Callable, DefaultDict, Optional, Type, get_type_hints, Union
11-
from types import UnionType
12-
from flask import current_app, make_response
10+
from typing import Dict, Type, Callable, List, Tuple, Optional, Any, DefaultDict, Union
11+
from typing import get_args, get_origin, get_type_hints
12+
13+
try:
14+
from types import UnionType # type: ignore
15+
except ImportError: # pragma: no cover
16+
# python < 3.10
17+
UnionType = Union # type: ignore
18+
19+
from flask import make_response, current_app
1320
from flask.wrappers import Response as FlaskResponse
1421
from pydantic import BaseModel, ValidationError
1522
from pydantic.json_schema import JsonSchemaMode

0 commit comments

Comments
 (0)