Skip to content

Commit 1661587

Browse files
committed
Add docs
1 parent d32452d commit 1661587

9 files changed

+226
-4
lines changed

docs/Usage/Request.md

Lines changed: 83 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,88 @@ def get_book(raw: BookRaw):
103103
return "ok"
104104
```
105105

106+
## Multiple content types in the request body
107+
108+
```python
109+
from typing import Union
110+
111+
from flask import Request
112+
from pydantic import BaseModel
113+
114+
from flask_openapi3 import OpenAPI
115+
116+
app = OpenAPI(__name__)
117+
118+
119+
class DogBody(BaseModel):
120+
a: int = None
121+
b: str = None
122+
123+
model_config = {
124+
"openapi_extra": {
125+
"content_type": "application/vnd.dog+json"
126+
}
127+
}
128+
129+
130+
class CatBody(BaseModel):
131+
c: int = None
132+
d: str = None
133+
134+
model_config = {
135+
"openapi_extra": {
136+
"content_type": "application/vnd.cat+json"
137+
}
138+
}
139+
140+
141+
class BsonModel(BaseModel):
142+
e: int = None
143+
f: str = None
144+
145+
model_config = {
146+
"openapi_extra": {
147+
"content_type": "application/bson"
148+
}
149+
}
150+
151+
152+
class ContentTypeModel(BaseModel):
153+
model_config = {
154+
"openapi_extra": {
155+
"content_type": "text/csv"
156+
}
157+
}
158+
159+
160+
@app.post("/a", responses={200: DogBody | CatBody | ContentTypeModel | BsonModel})
161+
def index_a(body: DogBody | CatBody | ContentTypeModel | BsonModel):
162+
"""
163+
multiple content types examples.
164+
165+
This may be confusing, if the content-type is application/json, the type of body will be auto parsed to
166+
DogBody or CatBody, otherwise it cannot be parsed to ContentTypeModel or BsonModel.
167+
The body is equivalent to the request variable in Flask, and you can use body.data, body.text, etc ...
168+
"""
169+
print(body)
170+
if isinstance(body, Request):
171+
if body.mimetype == "text/csv":
172+
# processing csv data
173+
...
174+
elif body.mimetype == "application/bson":
175+
# processing bson data
176+
...
177+
else:
178+
# DogBody or CatBody
179+
...
180+
return {"hello": "world"}
181+
```
182+
183+
The effect in swagger:
184+
185+
![](../assets/Snipaste_2025-01-14_10-44-00.png)
186+
187+
106188
## Request model
107189

108190
First, you need to define a [pydantic](https://github.com/pydantic/pydantic) model:
@@ -125,7 +207,7 @@ class BookQuery(BaseModel):
125207
author: str = Field(None, description='Author', json_schema_extra={"deprecated": True})
126208
```
127209

128-
Magic:
210+
The effect in swagger:
129211

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

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
@@ -287,6 +287,29 @@ class BookListAPIView:
287287
app.register_api_view(api_view)
288288
```
289289

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

292315
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: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
import sys
88
from enum import Enum
99
from http import HTTPStatus
10-
11-
from typing import get_type_hints, Dict, Type, Callable, List, Tuple, Optional, Any, DefaultDict, Union
10+
from typing import Dict, Type, Callable, List, Tuple, Optional, Any, DefaultDict, Union
11+
from typing import get_args, get_origin, get_type_hints
1212

1313
try:
1414
from types import UnionType # type: ignore
@@ -20,7 +20,6 @@
2020
from flask.wrappers import Response as FlaskResponse
2121
from pydantic import BaseModel, ValidationError
2222
from pydantic.json_schema import JsonSchemaMode
23-
from typing_extensions import get_args, get_origin
2423

2524
from .models import Encoding
2625
from .models import MediaType

0 commit comments

Comments
 (0)