fastapi的使用方法(13.FastAPIResponse对象)
在某些情况下,可能会需要对请求返回特定的数据,而不是采用默认的方式,此时,就可以直接使用Response对象在FastAPI中,可以在路由操作函数声明一个fastapi.Response类型的参数,然后在函数的代码直接操作Response对象,今天小编就来聊一聊关于fastapi的使用方法?接下来我们就一起去研究一下吧!
fastapi的使用方法
13.FastAPI Response对象在某些情况下,可能会需要对请求返回特定的数据,而不是采用默认的方式,此时,就可以直接使用Response对象。在FastAPI中,可以在路由操作函数声明一个fastapi.Response类型的参数,然后在函数的代码直接操作Response对象。
13.1更改响应状态码可以在路由操作函数中,通过对Response对象的 status_code 赋值来修改响应状态码,代码如下:
from fastapi import FastAPI
from fastapi import Response
from fastapi import status
app = FastAPI()
@app.get(path='/hello', status_code=status.HTTP_200_OK)
async def hello(response: Response):
response.status_code = status.HTTP_201_CREATED
return {'hello': 'world'}
执行请求后后台日志输出:
127.0.0.1:50876 - "GET /hello HTTP/1.1" 201 Created
在上面的代码中,虽然在装饰器中使用参数设置为返回状态码为200,但在函数中可以通过Response对象对返回状态码进行修改。
13.2JSON编码器在某些情况下,可能需要在 Pydantic模型与Python类型之间进行转换,目的是将数据转换为与JSON兼容的数据结构,比如:list、dict等。FastAPI提供 jsonable_encoder()函数来支持这样的数据转换。该函数接受一个Pydantic模型对象作为参数,返回一个对应的JSON兼容版本。
代码如下:
from fastapi import FastAPI
from pydantic import BaseModel
from datetime import datetime
from datetime import time
from fastapi.encoders import jsonable_encoder
app = FastAPI()
class Task(BaseModel):
name: str
created: datetime
runat: time
creator: str
@app.get(path='/test')
async def test():
task = Task(name='hello', created=datetime.now(), runat=time(hour=2,minute=30,second=0), creator='admin')
print(type(task))
enjson = jsonable_encoder(task)
print(type(enjson))
print(enjson)
return task
执行请求:
curl http://127.0.0.1:8000/test
{
"name":"hello",
"created":"2022-01-15T09:17:16.061638",
"runat":"02:30:00",
"creator":"admin"
}
后台print输出:
<class 'main2.Task'>
<class 'dict'>
{'name': 'hello', 'created': '2022-01-15T09:17:16.061638', 'runat': '02:30:00', 'creator': 'admin'}
从上面的代码及代码执行结果可以看出: 代码将 Pydantic 模型转换为一个字典,其值与JSON兼容,并将这个datetime和time转换为一个字符串。
事实上,在FastAPI内部是使用jsonable_encoder来转换数据的。
13.3 直接返回Response对象13.3.1 JSONResponse在前面的代码中,当创建一个FastAPI路由时,可以返回dict、list、Pydantic 模型等,那么FastAPI内部是如何处理的呢?FastAPI默认会使用 jsonable_encoder 将返回值转换为JSON格式, 然后,FastAPI 会在后台将这些兼容 JSON 的数据(比如字典)放到一个 JSONResponse 中,该 JSONResponse 会用来发送响应给客户端。
JSONResponse 是Response 的子类,Response 还有很多子类,在后面的内容中介绍。
13.3.2返回 Response实际上,可以直接返回Response或其任何子类,当直接返回Response时,FastAPI会直接传递它,FastAPI 不会用 Pydantic 模型做任何数据转换,不会将响应内容转换成任何类型。这种特性带来了极大的可扩展性,可以返回任何数据类型,重写任何数据声明或者校验等。
在下面的代码中,我们通过JSONResponse 人为返回我们希望返回的内容,代码如下:
from fastapi import FastAPI
from pydantic import BaseModel
from datetime import datetime
from datetime import time
from fastapi.encoders import jsonable_encoder
from fastapi.responses import JSONResponse
app = FastAPI()
class Task(BaseModel):
name: str
created: datetime
runat: time
creator: str
@app.get(path='/test')
async def test():
task = Task(name='hello', created=datetime.now(), runat=time(hour=2,minute=30,second=0), creator='admin')
jTask = jsonable_encoder(task)
return JSONResponse(content=jTask)
执行请求:
curl http://127.0.0.1:8000/test
{"name":"hello","created":"2022-01-15T10:53:33.009967","runat":"02:30:00","creator":"admin"}
在FastAPI中,Response接受如下参数:
- content str 或者 bytes。
- status_codeint 类型的 HTTP 状态码。
- headers 由字符串组成的 dict。
- media_type 给出媒体类型的 str,比如 "text/html"。
可以直接返回Response,示例代码如下:
from fastapi import FastAPI
from fastapi import Response
app = FastAPI()
@app.get(path='/test')
async def test():
data = '''<?xml version="1.0"?>
<shampoo>
<Header>
Apply shampoo here.
</Header>
<Body>
You'll have to use soap here.
</Body>
</shampoo>
'''
return Response(content=data, media_type="application/xml")
执行请求:
curl http://127.0.0.1:8000/test
<?xml version="1.0"?>
<shampoo>
<Header>
Apply shampoo here.
</Header>
<Body>
You'll have to use soap here.
</Body>
</shampoo>
- HTMLResponse接受文本或字节并返回 HTML 响应。
- PlainTextResponse接受文本或字节并返回纯文本响应。
- JSONResponse接受数据并返回一个 application/json 编码的响应,是 FastAPI 中使用的默认响应。
- ORJSONResponseORJSONResponse 是一个使用orjson的快速的可选 JSON 响应。
- UJSONResponseUJSONResponse 是一个使用 ujson的可选 JSON 响应。
- RedirectResponse返回 HTTP 重定向。默认情况下使用 307 状态代码(临时重定向)。
- StreamingResponse采用异步生成器或普通生成器/迭代器,然后流式传输响应主体。
- FileResponse异步传输文件作为响应。
使用这些子类的方法:
- 可以在路径操作装饰器中通过 response_class 参数声明想要返回的 Response
- 路由操作函数中将返回的内容将被放在对应的Response中 , 如果该 Response 有一个 JSON 媒体类型(application/json),比如使用 JSONResponse 或者 UJSONResponse 的时候,返回的数据将使用在路径操作装饰器中声明的任何 Pydantic 的 response_model 自动转换(和过滤)。
ORJSONResponse在性能上有所提高,使用ORJSONResponse需要安装orjson,执行:
pip install orjson
代码如下:
from fastapi import FastAPI
from pydantic import BaseModel
from datetime import datetime
from datetime import time
from fastapi.responses import ORJSONResponse
app = FastAPI()
class Task(BaseModel):
name: str
created: datetime
runat: time
creator: str
@app.get(path='/test', response_class=ORJSONResponse)
async def test():
task = Task(name='hello', created=datetime.now(), runat=time(hour=2,minute=30,second=0), creator='admin')
return task
代码如下:
from fastapi import FastAPI
from fastapi.responses import HTMLResponse
app = FastAPI()
@app.get(path='/test')
async def test():
data = '''
<html>
<head>
<title>Some HTML in here</title>
</head>
<body>
<h1>Look ma! HTML!</h1>
</body>
</html>
'''
return HTMLResponse(content=data)
上面的代码没有使用response_class 参数,而是直接返回相应的HTMLResponse。
13.5.3PlainTextResponse代码如下:
from fastapi import FastAPI
from fastapi.responses import PlainTextResponse
app = FastAPI()
@app.get(path='/test', response_class=PlainTextResponse)
async def test():
data = 'Hello FastAPI!!!'
return data
在处理某些边缘情况时,ujson 不如 Python 的内置实现那么谨慎。需要安装ujson
pip install ujson
代码如下:
from fastapi import FastAPI
from pydantic import BaseModel
from datetime import datetime
from datetime import time
from fastapi.responses import UJSONResponse
app = FastAPI()
class Task(BaseModel):
name: str
created: datetime
runat: time
creator: str
@app.get(path='/test', response_class=UJSONResponse)
async def test():
task = Task(name='hello', created=datetime.now(), runat=time(hour=2,minute=30,second=0), creator='admin')
return task
代码如下:
from fastapi import FastAPI
from fastapi.responses import RedirectResponse
app = FastAPI()
@app.get(path='/test')
async def test():
return RedirectResponse("https://www.baidu.com")
代码如下:
from fastapi import FastAPI
from fastapi.responses import StreamingResponse
app = FastAPI()
@app.get(path='/test')
async def test():
async def read_data():
for i in range(10):
data = 'hello fastapi {0} \r\n'.format(i)
yield data
return StreamingResponse(content=read_data())
执行请求:
curl http://127.0.0.1:8000/test
hello fastapi 0
hello fastapi 1
hello fastapi 2
hello fastapi 3
hello fastapi 4
hello fastapi 5
hello fastapi 6
hello fastapi 7
hello fastapi 8
hello fastapi 9
使用StreamingResponse实现流式下载文件,代码如下:
from fastapi import FastAPI
from fastapi.responses import StreamingResponse
app = FastAPI()
@app.get(path='/test')
async def test():
def read_file():
with open('Apache_OpenOffice_4.1.11_Win_x86_install_en-US.exe', 'rb') as f:
yield from f
return StreamingResponse(content=read_file())
当使用浏览器访问http://127.0.0.1:8000/test时开始下载文件。
13.5.7FileResponse该响应接受不同的参数进行实例化:
- path 要流式传输的文件的文件路径。
- headers 任何自定义响应头,传入字典类型。
- media_type给出媒体类型的字符串。如果未设置,则文件名或路径将用于推断媒体类型。
- filename如果给出,它将包含在响应的 Content-Disposition 中。
代码如下:
from fastapi import FastAPI
from fastapi.responses import FileResponse
app = FastAPI()
@app.get(path='/test')
async def test():
return FileResponse(path='Apache_OpenOffice_4.1.11_Win_x86_install_en-US.exe')
当使用浏览器访问http://127.0.0.1:8000/test时开始下载文件。
,
免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com