杭州电信网站备案,html5的广泛应用,内蒙古呼和浩特邮编,网站和h511-1 直接使用Request对象 关于请求的操作#xff0c;比如从URL中提取路径参数#xff0c;获取查询参数#xff0c;获取请求头#xff0c;获取Cookie#xff0c;获取请求体中的数据#xff1b;这些参数和值的获取非常方便#xff0c;这是因为FastAPI帮我们创造便利。 F…11-1 直接使用Request对象 关于请求的操作比如从URL中提取路径参数获取查询参数获取请求头获取Cookie获取请求体中的数据这些参数和值的获取非常方便这是因为FastAPI帮我们创造便利。 FastAPI底层依赖Starlette本质上是FastAPI帮我们做了一些操作从Starlette的Request对象解析出上述各个参数。 所以对于上面这些常用的请求参数我们可以直接使用FastAPI给我们提供的工具并且有了数据校验、类型转化、OPenAPI文档等功能。 当然了你不使用FastAPI提供的便捷工具直接从Request对象中解析数据也是可以的但就没由数据校验、类型转化、OPenAPI文档等功能。 不过有些场景比如说获取请求的IP请求的client host等等那我们就必须直接使用Request对象。
示例1使用使用Request获取常见参数
from fastapi import FastAPI, Request
from starlette.requests import Requestapp FastAPI()app.get(/{item_id})
def hello(req: Request):item_id req.path_params.get(item_id)page req.query_params.get(page, 0)size req.query_params.get(size, 10)x_token req.headers.get(x-token)x_token_cookie req.cookies.get(x_token)return {item_id: item_id,page: page,size: size,x-token: x_token,cookie: x_token_cookie,}示例2使用Request获取客户端host
从fastapi导入 Request对象或者直接从 starlette.requests导入 Request 两者是一样的效果。本例中路径参数 item_id是用的FastAPI提供的便捷方式所以具有类型转换、类型校验、openapi文档等附加功能。第二个形参 req 的类型是 Request那FastAPI就知道要直接从Request中获取参数就没有上述附加功能。
from fastapi import FastAPI, Request
from starlette.requests import Request app FastAPI()app.get(/item/{item_id})
def hello(item_id: int, req: Request):return {item_id: item_id,client_host: req.client.host}补充直接从Request中获取请求体参数需要使用async/await语法在下一章我们再详细介绍。
11-2 直接使用Response对象 关于响应的操作在前面的章节有涉及到比如设置响应状态码设置响应头在路径函数内返回数据就可以当做响应体。 这些都是FastAPI给我们提供的便捷方式使用了这些方式几乎帮助我们处理了大部分常见的需求。 不过在一些特殊常场景下我们需要更加灵活的处理响应。 比如我们已经使用过了通过Response对象来设置Cookie, 设置响应头等等。 本质上FastAPI借用了Starlette框架的Response对象即我们使用的Response对象都是Starlette的。 Response对象还有很多其他高进的用法比如处理重定向、响应其他格式的数据纯文本/HTML/XML/下载文件等等。
示例1使用Response设置状态码/响应头/cookie
从FastAPI导入的Response等价于从starlette.responses导入的Response在路径函数中定义的形参response的类型是ResponseFastAPI可以是被出来你要手动使用Response对象但是这样的使用方式本质上依然使用了FastAPI的便捷方式因为你返回的是123但其实响应格式是application/json这是因为FastAPI的默认响应方式是JSONResponse即所有的返回给客户端的数据都会被json序列化
from fastapi import FastAPI, Response
from starlette.responses import Responseapp FastAPI()app.get(/)
def hello(response: Response):response.status_code 201response.headers[x-token] 12345response.set_cookie(token, 111111, 100)return 123示例2直接返回Response对象
Response类初始化对象一般需要四个参数content是响应体的数据必须是支持编码的字符串。如果要返回的数据是字段则要使用json序列化status_code 设置响应的状态码headers 设置响应头media_type 设置响应类型比如说是json格式的数据则值为 application/json
import json
from fastapi import FastAPI, Response
from starlette.responses import Responseapp FastAPI()app.get(/, )
def hello():response Response(contentjson.dumps({hello: world}),status_code201,headers{x-token: qqqqqq},media_typeapplication/json)return response11-3 默认响应方式
上节课我们知道可以直接返回Response对象使用起来也比较简单只需要在实例化对象是按照要求传参即可。
但是你会发现不同类型的响应数据都需要手动传参这是比较麻烦的。
其实FastAPI提供了多种内置的响应方式比如对于JSON格式的响应数据提供了JSONResponse这种响应类型。
本质上JSONResponse类是Response这个类的子类并且JSONResponse是FastAPI中的默认响应方式。
示例1:
此时直接返回的是字典但FastAPI内部帮我们处理返回的数据格式是json的。想要修改内置响应方式可修改FastAPI()中或的APIRouter()中的 default_response_class还可以对于指定接口通过 response_class设置响应方式优先级接口 router app
from fastapi import FastAPI, APIRouter
from fastapi.responses import JSONResponseapp FastAPI(default_response_classJSONResponse) # 设置全局的默认响应方式
router APIRouter(default_response_classJSONResponse) # 设置APIRouter所有接口的默认响应方式app.get(/, response_classJSONResponse) # 设置这个接口的默认响应方式
def hello():return {id: 1, name: liixu}示例2源码阅读
JSONResponse是Response的子类m默认写死 media_type application/json并重写了render方法该方法会在示实例化响应对象时触发用来把我们传进去的 content序列化。因此使用手动JSONResponse时需要保证content是可序列化的否则报错。
class JSONResponse(Response): media_type application/jsondef __init__(self,content: typing.Any,status_code: int 200,headers: typing.Optional[dict] None,media_type: typing.Optional[str] None,background: typing.Optional[BackgroundTask] None,) - None:super().__init__(content, status_code, headers, media_type, background)def render(self, content: typing.Any) - bytes:return json.dumps(content,ensure_asciiFalse,allow_nanFalse,indentNone,separators(,, :),).encode(utf-8)11-4 文本相关的Response
和文本相关的有两种响应方式 PlainTextResponse HTMLResponse
示例1PlainTextResponse用来响应纯文本的数据
PlainTextResponse是Response的子类重写了media_type “text/plain”对应响应头中的 content-type: text/plain此时网页上显示纯文本信息。
from fastapi import FastAPI
from fastapi.responses import PlainTextResponseapp FastAPI()app.get(/, response_classPlainTextResponse)
def main():return Hello World示例2HTMLResponse用来响应HTML页面
HTMLResponse是Response的子类重写media_type “text/html”就可以直接返回HTMLResponse对象网页渲染HTML样式。
from fastapi import FastAPI
from fastapi.responses import HTMLResponseapp FastAPI()app.get(/)
def index():html_content htmlheadtitleSome HTML in here/title/headbodyh1Look ma! HTML!/h1/body/htmlreturn HTMLResponse(contenthtml_content, status_code200)示例3使用response_classHTMLResponse此时可以直接返回HTML的文本此时网页上依然渲染HTML样式。
使用response_classHTMLResponse的另一个好处是可以在openapi文档上显示返回HTML的提示。
from fastapi import FastAPI
from fastapi.responses import HTMLResponseapp FastAPI()app.get(/, response_classHTMLResponse)
def index():return htmlheadtitleSome HTML in here/title/headbodyh1Look ma! HTML!/h1/body/html11-5 下载文件相关的Response
下载文件相关的响应类有两个
StreamingResponseFileResponse
示例1StreamingResponse支持文件类型的操作下载文件
from fastapi import FastAPI
from fastapi.responses import StreamingResponseapp FastAPI()app.get(/)
def index():def iterfile(): #with open(mybook.zip, moderb) as f: #yield from freturn StreamingResponse(iterfile(), media_typeapplication/zip)示例2使用FileResponse
更加直接时候文件下载。
from fastapi import FastAPI
from fastapi.responses import FileResponseapp FastAPI()app.get(/)
def index():return FileResponse(mybook.zip, filenamebook.zip) # 第一个参数文件路径filename指定下载下来的文件名11-6 其他Response
示例1重定向Response
from fastapi import FastAPI
from fastapi.responses import RedirectResponseapp FastAPI()app.get(/)
def go_to_baidu():return RedirectResponse(https://www.baidu.com)示例2ORJSONResponse
ORJSONResponse是一个基于orjson序列化的响应类它在性能上要由于JSONResponse使用是需要安装 pip3 install orjson
from fastapi import FastAPI
from fastapi.responses import ORJSONResponseapp FastAPI()app.get(/, response_classORJSONResponse)
def go_to_baidu():return {id: 1, name: liuxu}补充继承Response 模仿者其他响应类定义自己的响应类自己实现吧。