Fastapi教程002

 

Path参数

简单demo

  1. 你可以使用python字符串进行变量的声明,代码如下:

 from fastapi import FastAPI

 app = FastAPI()


 @app.get("/items/{item_id}")
 async def read_item(item_id):
   return {"item_id": item_id}

上面代码的含义是: 路径参数 item_id 将作为 read_item方法的参数,当通过uvicorn main:app --reload将服务跑起来后,可通过http://127.0.0.1:8000/items/foo进行访问,在浏览器中将会返回 {"item_id":"foo"}

  1. Path参数类型

简单来说Path参数可使用标准的Python类型,例如 int str dict等类型去定义

简单示范一下:

  from fastapi import FastAPI

  app = FastAPI()

  @app.get("/items/{item_id}")
  async def read_item(item_id: int):
​    return {"item_id": item_id}

    在上面的代码中我们可以看到参数 item_id的类型是int, 所以具体将参数定义为什么类型可根据自己的业务需求进行调整,并且我们自己定义的类型还可以进行数据的转换。

  1. 数据类型转换
  • 当我们通过浏览器输入 http://127.0.0.1:8000/items/3 的时候我们可以收到返回值 {"item_id":3} 这里的 3int 类型的,而不是字符串str 类型

    1. 数据验证
  • 当我们在浏览器中输入 http://127.0.0.1:8000/items/foo的时候,我们将会收到以下错误:

{
    "detail": [
        {
            "loc": [
                "path",
                "item_id"
            ],
            "msg": "value is not a valid integer",
            "type": "type_error.integer"
        }
    ]
}
  • 其中 loc中显示的就是我们的错误信息, 字段为 路径参数 item_idmsg显示的是错误的具体原因, 由于我们将item_id 设置为Int 类型,所以当我们在浏览器中输入foo的时候,该方法会自动进行数据格式的验证,并将错误信息返回。

    1. 文档

    当打开浏览器输入http://127.0.0.1:8000/docs的时候我们就可以进入到该文档页面:

avatar

  • 本文档可分为四大部分,第一部分是 路由部分,你可以看到 当前方法的路由是 items/{item_id}

  • 第二部分是参数部分即Parameters,此部分是填写方法需要的参数

  • 第三部分是 Response即响应体,在此部分你可以看到 返回值状态码,返回值具体信息等

  • 第四部分是 Validata部分,此部分主要展示定义的各种数据验证方法

Pydantic

概述:所有的数据格式验证都是由Pydantic实现的,我们不必关心它是如何工作的。我们可以根据自己的需求进行格式的声明验证,例如上面的 int 类型和 str类型,具体内容将会在下一节阐述.

路径顺序

当我们进行路由的声明时,你可以发现这些路由路径都是固定的。

就像 /users/me 根据restful的命名规范,我们可以看到这是获取 当前用户信息,

/users/{user_id} 是根据用户的id user_id 获取用户的信息,所以在定义的时候需要注意一下:

  from fastapi import FastAPI

  app = FastAPI()


  @app.get("/users/me")
  async def read_user_me():
      return {"user_id": "the current user"}


  @app.get("/users/{user_id}")
  async def read_user(user_id: str):
      return {"user_id": user_id}

就像上面代码写的一样,当我们想要获取 路由为me的用户的信息时,如果上面两个方法路由顺序颠倒,则会出现 user_id = me的现象,因此我们在路由书写上需要注意顺序。

预定义值

如果我们想要在Path参数上添加一些选项,我们可以使用枚举 Enum 进行设置,例如用户在注册网站的时候需要选择一个安全问题,我们就可以用这个方式实现具体演示如下。

  from enum import Enum

  from fastapi import FastAPI


​    alexnet = "alexnet"

​    resnet = "resnet"

​    lenet = "lenet"


  @app.get("/model/{model_name}")

  async def get_model(model_name: ModelName):

​    if model_name == ModelName.alexnet:

​      return {"model_name": model_name, "message": "Deep Learning FTW!"}

​    if model_name.value == "lenet":

​      return {"model_name": model_name, "message": "LeCNN all the images"}

​    return {"model_name": model_name, "message": "Have some residuals"}

上面的代码主要就是定义了一个枚举类ModelName,定义了一个 get_model方法,并且这个方法的Path参数就是ModelName,主要实现功能就是在发请求的时候让用户选择 model_name的如下图所示,如同选择注册安全问题一样,具体演示可以通过交互式文档自我体验。

avatar

Path参数接收 path 文件路径

举个例子: 我们现在有一个路径参数 /files/{file_path},但是 file_paht表示需要传一个文件,文件路径是本地的home/johndoe/myfile.txt,所以最后的Path路径看起来是 /files/home/johndoe/myfile.txt。这种方式在Fastapi中是不建议这么写的,因为我们在URL中基本都是不会直接拼接某个文件的地址的,而是在参数中进行上传文件,因此需要稍微改动一下,将/files/{file_path}改为/files/{file_path:path},这意味着我们的代码更加优雅。 代码如下:

OpenAPI 本身并不支持定义包含path的路径参数,因此这可能导致难以定义和测试。 不过, 使用 Starlette的内置工具仍然可以在 FastAPI 中实现该功能。 并且支持交互文档,只是文档中并不会添加任何说明,告诉你这个参数可能应该Path。

  from fastapi import FastAPI

  app = FastAPI()


  @app.get("/files/{file_path:path}")
  async def read_user_me(file_path: str):
      return {"file_path": file_path}

在这种情况下,参数的名称为file_path,最后一部分:path告诉它该参数应与任何路径匹配。

总结

  • Path 路径参数可以实现路由参数传递

  • 数据格式检查

  • 数据解析

  • API批注和自动文档

  • 可在文档中进行交互调试(这个真的很有用)