fastapi的使用方法(13.FastAPIResponse对象)

在某些情况下,可能会需要对请求返回特定的数据,而不是采用默认的方式,此时,就可以直接使用Response对象在FastAPI中,可以在路由操作函数声明一个fastapi.Response类型的参数,然后在函数的代码直接操作Response对象,今天小编就来聊一聊关于fastapi的使用方法?接下来我们就一起去研究一下吧!

fastapi的使用方法(13.FastAPIResponse对象)

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"}

13.4Response

在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>

13.5Response子类
  • HTMLResponse接受文本或字节并返回 HTML 响应。
  • PlainTextResponse接受文本或字节并返回纯文本响应。
  • JSONResponse接受数据并返回一个 application/json 编码的响应,是 FastAPI 中使用的默认响应。
  • ORJSONResponseORJSONResponse 是一个使用orjson的快速的可选 JSON 响应。
  • UJSONResponseUJSONResponse 是一个使用 ujson的可选 JSON 响应。
  • RedirectResponse返回 HTTP 重定向。默认情况下使用 307 状态代码(临时重定向)。
  • StreamingResponse采用异步生成器或普通生成器/迭代器,然后流式传输响应主体。
  • FileResponse异步传输文件作为响应。

使用这些子类的方法:

  1. 可以在路径操作装饰器中通过 response_class 参数声明想要返回的 Response
  2. 路由操作函数中将返回的内容将被放在对应的Response中 , 如果该 Response 有一个 JSON 媒体类型(application/json),比如使用 JSONResponse 或者 UJSONResponse 的时候,返回的数据将使用在路径操作装饰器中声明的任何 Pydantic 的 response_model 自动转换(和过滤)。
13.5.1ORJSONResponse

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

13.5.2 HTMLResponse

代码如下:

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

13.5.4UJSONResponse

在处理某些边缘情况时,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

13.5.5RedirectResponse

代码如下:

from fastapi import FastAPI from fastapi.responses import RedirectResponse app = FastAPI() @app.get(path='/test') async def test(): return RedirectResponse("https://www.baidu.com")

13.5.6StreamingResponse

代码如下:

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

    分享
    投诉
    首页