1 绑定路由到路由组
这篇文章继续介绍现代的接口管理方式和框架fastapi ,一起了解其主要内容。
2 路由URL中的查询参数
声明不属于路径参数的其他函数参数时,它们将被自动解释为"查询字符串"参数 如下skip limit都是查询参数。
参数解释:
返回json 格式,原始值 为字符串
http://127.0.0.1:1999/items/?skip=0&limit=1 # 限制查一个
http://127.0.0.1:1999/items/?skip=0&limit=10 # 限制查10个
:param skip: 对于的值为0
:param limit: 对于的值 10
参数原始值为 字符串,当你为它们声明一个Python类型时,
它们将转换为该类型并针对该类型进行校验
:return:
代码:
@app.get("/items/")
async def read_time(skip: int = 0, limit: int = 10):
return fake_items_db[skip:skip + limit]
当你为它们声明了python类型,它们将转换为该类型并针对该类型进行校验。
应用于该路径参数的所有相同过程也适用于查询参数。
编辑器支持
数据解析
数据校验
自动生成文档
默认值
查询参数可以有默认值
skip=0,limit=10 就是默认值
可选参数
使用设置None声明可选参数
多个路径参数和 查询参数
注意 如果 q 和 short 没有默认值 那就是必填查询参数
在这个例子中,有2个查询参数:user_id: int, user_id 必须的int类型 路径参数。 item_id:str item_id 必须的str 类型 路径参数 q,一个必须的 没有默认值的str 类型参数。 short,一个可选的 bool 类型参数。 @app.get("/user/{user_id}/items/{item_id}") # 多个路径参数 和 查询参数 async def read_user_check(user_id: int, item_id:str, q: Optional[str], short:bool=False):
q 是可选字符串参数 默认为 None
FastAPI可以分辨 参数 item_id 是路径参数,而q不是,因此q是查询参数
查询参数类型转换 声明不属于路径参数的其他函数参数时,它们将被自动解释为"查询字符串"参数short: 是否排序 short=on 就是查询参数,FastAPI可以 识别 on,yes,True,true,1 为 python的True > http://127.0.0.1:1999/user/1/items/2?q=ok&short=false < response: {"item_id":"2","own_id":1,"q":"ok","description":"This is an amazing item that has a long description"}
3 路径装饰器
传递参数给路径操作装饰器 ,即可轻松地配置路径操作、添加元数据。
参数为:tags 和 status_code 和 response_model
@ 使用 status 快捷常量 HTTP_201_CREATED
@ 使用 tags 为路径操作 添加标签,tag一般由 str组成的 list构成, 可以用于 api 接口分组
@ response_model 定义返回数据结构模型
@app.post("/items/create", response_model=Item, status_code=status.HTTP_201_CREATED, tags=["items"])
async def create_item(item:Item):
return item
@ summary 将在docs的 api右侧显示
@ description参数 与接口的docs 描述一样的效果
@ response_description 在docs中显示响应描述
@ , deprecated=True 可以将路径操作标记为弃用,无需直接删除,
docs中将显示 此接口为灰色
POST /items/create Create an item
如果 description参数 与接口的docs 都设置了,那么只会显示一个描述 默认为路径中定义的,
路径装饰器 的高级设置
通过参数opeeration_id 设置 要使用的OpenAPO operationId
** 务必确保每个操作路径的 opeeration_id都是唯一的
注释不输出到 api docs
添加一个 \f (一个「换页」的转义字符)可以使 FastAPI 在那一位置截断用于 OpenAPI 的输出。
剩余部分不会出现在文档中,但是其他工具(比如 Sphinx)可以使用剩余部分。
4 路由响应
https://fastapi.tiangolo.com/zh/advanced/custom-response/
FastAPI 默认会使用 JSONResponse 返回响应
FastAPI 默认帮你把这个 item 放到 JSONResponse 中,又默认将其转换成了 dict,可以使用 Response重载,因为 JSONResponse 本身是一个 Response 的子类。
对于这些情况,在将数据传递给响应之前,你可以使用 jsonable_encoder 来转换你的数据。
使用api route的名称作为 operation_id
from controlers.apiroute import use_route_names_as_operation_ids
from fastapi.responses import JSONResponse
from fastapi.encoders import jsonable_encoder
# from starlette import status
技术细节 于 从fastapi 导入 status是一样的
你也可以使用 from starlette.responses import JSONResponse。
出于方便,FastAPI 会提供与 starlette.responses 相同的 fastapi.responses 给开发者。
但是大多数可用的响应都直接来自 Starlette。
返回自定义response
return Response(content=data, media_type="application/xml")
XML响应
HTML响应
文档和重载Response
直接返回 HTMLResponsedef generate_html_response(): html_content = """ <html> Look </html> """ return HTMLResponse(content=html_content, status_code=200) @app.get("/items/", response_class=HTMLResponse) async def read_items(): return generate_html_response()
response_class 中也传入了 HTMLResponse,FastAPI 会知道如何在 OpenAPI 和交互式文档中使用 text/html 将其文档化为 HTML。
通过返回函数 generate_html_response() 的调用结果,你已经返回一个重载 FastAPI 默认行为的 Response 对象
5 可用响应及自定义响应
使用 Response 来返回任何其他东西,甚至创建一个自定义的子类:
content - 一个 str 或者 bytes。
status_code - 一个 int 类型的 HTTP 状态码。
headers - 一个由字符串组成的 dict。
media_type - 一个给出媒体类型的 str,比如 "text/html"。
纯文本响应
PlainTextResponse
UJSONResponse
response_class=UJSONResponse
在处理某些边缘情况时,ujson 不如 Python 的内置实现那么谨慎。
UJSONResponse 是一个使用 ujson 的可选 JSON 响应
重定向 RedirectResponse ,返回 HTTP 重定向。默认情况下使用 307 状态代码(临时重定向)。
return RedirectResponse("https://typer.tiangolo.com")
响应流 StreamingResponse 采用异步生成器或普通生成器/迭代器,然后流式传输响应主体
return StreamingResponse(fake_video_streamer())
对类似文件的对象使用 StreamingResponse,如果您有类似文件的对象(例如,由 open() 返回的对象),则可以在 StreamingResponse 中将其返回。
包括许多与云存储,视频处理等交互的库。
@app.get("/")
def main():
def iterfile(): # (1)
with open(some_file_path, mode="rb") as file_like: # (2)
yield from file_like # (3)
return StreamingResponse(iterfile(), media_type="video/mp4")
文件流FileResponse,异步传输文件作为响应。
与其他响应类型相比,接受不同的参数集进行实例化:
path - 要流式传输的文件的文件路径。
headers - 任何自定义响应头,传入字典类型。
media_type - 给出媒体类型的字符串。如果未设置,则文件名或路径将用于推断媒体类型。
filename - 如果给出,它将包含在响应的 Content-Disposition 中。
文件响应将包含适当的响应头,包含适当的 Content-Length,Last-Modified 和 ETag 的响应头。
@app.get("/")
async def main():
return FileResponse(some_file_path)
响应的其他文档:
https://fastapi.tiangolo.com/zh/advanced/additional-responses/
CORS资源跨域共享和 资源访问限制
指浏览器中运行的前端拥有与后端通信的 JavaScript 代码,而后端处于与前端不同的「源」的情况
源是协议 http,https
域是 localhost,localhost.tiangolo.com 及端口 80 443 8080 的组合
因此 这些都是不同的源 因为协议和端口不同
http://localhost
https://localhost
http://localhost:8080
假设浏览器有一个前端运行在http://localhost:8080
js 正在尝试与 http://localhost 后端通信,因为我们没有指定端口默认为80
然后 浏览器向后端发送一个 http OPTIONS请求。
如果后端发送适当的 headers 来授权来着这个不同源 8080 端口的通信。
浏览器将允许前端 js向后端发送请求。
为此后端必须有一个 允许的源 列表 并且包括 8080 端口。
6 通配符
也可以使用 * 声明这个列表,表示全部都允许。
但这仅允许某些类型通信,不包括所有涉及凭据的内容。
如Cookies 以及那些使用Bearer令牌授权 headers,所以最好显式设置指定允许的源。
使用 CORSMiddlewware 步骤:
导入
创建一个允许的源列表
将其作为 中间件添加到 FastAPI
也可以指定后端是否允许:
凭证 授权headers cookies等
特定的HTTP方法
特定的HTTP headers 或使用通配符 * 允许所有headers
这个 CORSMiddleware 实现所使用的默认参数较为保守,所以你需要显式地启用特定的源、方法或者 headers,以便浏览器能够在跨域上下文中使用它们。
支持以下参数:
allow_origins - 一个允许跨域请求的源列表。例如 ['https://example.org', 'https://www.example.org']。你可以使用 ['*'] 允许任何源。
allow_origin_regex - 一个正则表达式字符串,匹配的源允许跨域请求。例如 'https://.*\.example\.org'。
allow_methods - 一个允许跨域请求的 HTTP 方法列表。默认为 ['GET']。你可以使用 ['*'] 来允许所有标准方法。
allow_headers - 一个允许跨域请求的 HTTP 请求头列表。默认为 []。你可以使用 ['*'] 允许所有的请求头。Accept、Accept-Language、Content-Language 以及 Content-Type 请求头总是允许 CORS 请求。
allow_credentials - 指示跨域请求支持 cookies。默认是 False。另外,允许凭证时 allow_origins 不能设定为 ['*'],必须指定源。
expose_headers - 指示可以被浏览器访问的响应头。默认为 []。
max_age - 设定浏览器缓存 CORS 响应的最长时间,单位是秒。默认为 600。
中间件响应两种特定类型的 HTTP 请求……
CORS预检请求
带有 Origin 和 Access-Control-Request-Method请求头的OPTIONS请求 这时,中间件将拦截传入的请求并进行响应 出于提供信息的目的返回一个使用了适当CORS headers的200 或 400 响应
简单请求
任何带有Origin请求头的请求。这时 中间件将像平常一样传递请求 在响应中包含适当的CORS headers
7 小结
我们在两个章节中,介绍这种新的业务提供框架,它的性能比流行框架更高,但是功能和稳定性稍差,依据业务选择可以分别考量。
这个