在框架中绑定http路由到路由组

举报
码乐 发表于 2024/03/09 11:12:01 2024/03/09
【摘要】 2 fastapi 绑定路由到路由组 2.1 路由URL中的查询参数声明不属于路径参数的其他函数参数时,它们将被自动解释为"查询字符串"参数 如下skip limit都是查询参数。参数解释: 返回json 格式,原始值 为字符串 http://127.0.0.1:1999/items/?skip=0&limit=1 # 限制查一个 http://127.0.0.1:19...

2 fastapi 绑定路由到路由组

2.1 路由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"}
    

2.2 路径装饰器

传递参数给路径操作装饰器 ,即可轻松地配置路径操作、添加元数据。

参数为: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)可以使用剩余部分。

2.3 路由响应

    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
    直接返回 HTMLResponse

      def 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 对象

2.3.1 可用响应及自定义响应

使用 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/

指浏览器中运行的前端拥有与后端通信的 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 端口。

2.4 通配符

也可以使用 * 声明这个列表,表示全部都允许。

但这仅允许某些类型通信,不包括所有涉及凭据的内容。

如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

3 小结

我们在两个章节中,介绍这种新的业务提供框架,它的性能比流行框架更高,但是功能和稳定性稍差,依据业务选择可以分别考量。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。