FastAPI 教程翻译 - 用户指南 3 - 路径参数

FastAPI 教程翻译 - 用户指南 3 - 路径参数

FastAPI Tutorial - User Guide - Path Parameters

You can declare path “parameters” or “variables” with the same syntax used by Python format strings:

您可以使用 Python 格式字符串使用的相同语法声明路径『参数』或『变量』:

from fastapi import FastAPI

app = FastAPI()


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

The value of the path parameter item_id will be passed to your function as the argument item_id.

路径参数 item_id 的值将作为参数 item_id 传递给您的视图函数。

So, if you run this example and go to http://127.0.0.1:8000/items/foo, you will see a response of:

因此,如果运行此示例并转到 http://127.0.0.1:8000/items/foo ,您将看到以下响应:

{"item_id":"foo"}

Path parameters with types

路径参数的类型

You can declare the type of a path parameter in the function, using standard Python type annotations:

您可以使用标准的 Python 类型注释在函数中声明路径参数的类型:

from fastapi import FastAPI

app = FastAPI()


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

In this case, item_id is declared to be an int.

在这种情况下,item_id 被声明为 int

Check

检查

This will give you editor support inside of your function, with error checks, completion, etc.

这将为您提供函数的编辑器支持,包括错误检查,完整性检查等。

Data conversion

数据转换

If you run this example and open your browser at http://127.0.0.1:8000/items/3, you will see a response of:

如果运行此示例并在浏览器中打开 http://127.0.0.1:8000/items/3 ,您将看到以下响应:

{"item_id":3}

Check

检查

Notice that the value your function received (and returned) is 3, as a Python int, not a string "3".

请注意,函数收到(并返回)的值是 Python 的 int 值(即 3),而不是字符串『3』

So, with that type declaration, FastAPI gives you automatic request “parsing”.

因此,有了类型声明,FastAPI 会为您自动提供请求『解析』。

Data validation

数据验证

But if you go to the browser at http://127.0.0.1:8000/items/foo, you will see a nice HTTP error of:

如果您通过浏览器进入 http://127.0.0.1:8000/items/foo ,会看到一个不错的 HTTP 错误页:

{
    "detail": [
        {
            "loc": [
                "path",
                "item_id"
            ],
            "msg": "value is not a valid integer",
            "type": "type_error.integer"
        }
    ]
}

because the path parameter item_id had a value of "foo", which is not an int.

因为路径参数 item_id 的值为『foo』,而不是 int

The same error would appear if you provided a float instead of an int, as in: http://127.0.0.1:8000/items/4.2

如果您提供的是 float 而不是 int,则会出现相似的错误,例如 http://127.0.0.1:8000/items/4.2

Check

检查

So, with the same Python type declaration, FastAPI gives you data validation.

因此,使用与 Python 类型声明相同的方式,FastAPI 可进行数据验证。

Notice that the error also clearly states exactly the point where the validation didn’t pass.

请注意,错误页清楚地指出了验证未通过的点。

This is incredibly helpful while developing and debugging code that interacts with your API.
在开发和调试与您的 API 交互的代码时,这非常有用。

Documentation

文档

And when you open your browser at http://127.0.0.1:8000/docs, you will see an automatic, interactive, API documentation like:

在浏览器上打开 http://127.0.0.1:8000/docs 时,您将看到一个自动的、交互式的 API 文档,例如:

在这里插入图片描述

Check

检查

Again, just with that same Python type declaration, FastAPI gives you automatic, interactive documentation (integrating Swagger UI).

同样,使用与 Python 类型声明相同的方式,FastAPI 为您提供自动的交互式文档(集成 Swagger UI)。

Notice that the path parameter is declared to be an integer.

请注意,路径参数已声明为整数。

Standards-based benefits, alternative documentation

基于标准的好处:备用文档

And because the generated schema is from the OpenAPI standard, there are many compatible tools.

由于生成的架构来自 OpenAPI 标准,因此有许多兼容工具。

Because of this, FastAPI itself provides an alternative API documentation (using ReDoc):

基于这个原因,FastAPI 本身提供了备用的 API 文档(使用 ReDoc):

在这里插入图片描述

The same way, there are many compatible tools. Including code generation tools for many languages.

同样,有许多的兼容工具。包括多种语言的代码生成工具。

Pydantic

All the data validation is performed under the hood by Pydantic, so you get all the benefits from it. And you know you are in good hands.

所有的数据验证都是由 Pydantic 实现的,因此您可以从中获得所有好处,而且您知道自己处于良好状态。

You can use the same type declarations with str, float, bool and many other complex data types.

同样的,您可以使用 strfloatbool 和许多其他复杂数据类型来进行声明。

Several of these are explored in the next chapters of the tutorial.

本教程的下一章将探讨其中的一些内容。

Order matters

顺序很重要

When creating path operations, you can find situations where you have a fixed path.

在创建路径操作时,您会发现路径固定的情况。

Like /users/me, let’s say that it’s to get data about the current user.

/users/me 一样,假设它是获取有关当前用户的数据。

And then you can also have a path /users/{user_id} to get data about a specific user by some user ID.

然后,您还可以使用路径 /users/{user_id} 来通过某些用户ID获取有关特定用户的数据。

Because path operations are evaluated in order, you need to make sure that the path for /users/me is declared before the one for /users/{user_id}:

因为路径操作是按照顺序评估的,所以您需要确保 /users/me 的路径在 /users/{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}

Otherwise, the path for /users/{user_id} would match also for /users/me, “thinking” that it’s receiving a parameter user_id with a value of "me".

否则,/users/{user_id} 的路径也将匹配 /users/me,『认为』它正在接收值为『me』的参数 user_id

Predefined values

预定义值

If you have a path operation that receives a path parameter, but you want the possible valid path parameter values to be predefined, you can use a standard Python Enum.

如果您的路径操作接收了路径参数,但是想要预定义可能的有效路径参数值,则可以使用标准 Python 的 Enum

Create an Enum class

创建一个 Enum

Import Enum and create a sub-class that inherits from str and from Enum.

导入 Enum 并创建一个继承自 strEnum 的子类。

By inheriting from str the API docs will be able to know that the values must be of type string and will be able to render correctly.

通过从 str 继承,API 文档将能够知道这些值必须是 string 类型才能正确呈现。

And create class attributes with fixed values, those fixed values will be the available valid values:

并创建具有固定值的类属性,这些固定值将是可用的有效值:

from enum import Enum

from fastapi import FastAPI


class ModelName(str, Enum):
    alexnet = "alexnet"
    resnet = "resnet"
    lenet = "lenet"


app = FastAPI()


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

Info

信息

Enumerations (or enums) are available in Python since version 3.4.

Enumerations (or enums) are available in Python 仅在 Python 3.4+ 提供支持。

Tip

提示

If you are wondering, “AlexNet”, “ResNet”, and “LeNet” are just names of Machine Learning models.

如果您想知道『AlexNet』、『ResNet』、『LeNet』,这些只是机器学习模型的名称。

Declare a path parameter

声明路径参数

Then create a path parameter with a type annotation using the enum class you created (ModelName):

然后使用您创建的 Enum 类(ModelName)创建带有类型注释的路径参数

from enum import Enum

from fastapi import FastAPI


class ModelName(str, Enum):
    alexnet = "alexnet"
    resnet = "resnet"
    lenet = "lenet"


app = FastAPI()


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

Check the docs

检查文档

Because the available values for the path parameter are specified, the interactive docs can show them nicely:

由于指定了路径参数的可用值,因此交互式文档可以很好地显示它们:

在这里插入图片描述

Working with Python enumerations

使用 Python 枚举

The value of the path parameter will be an enumeration member.

路径参数的值将是枚举成员

Compare enumeration members
比较枚举成员

You can compare it with the enumeration member in your created enum ModelName:

您可以将其与创建的 enum 类(ModelName)中的枚举成员进行比较:

from enum import Enum

from fastapi import FastAPI


class ModelName(str, Enum):
    alexnet = "alexnet"
    resnet = "resnet"
    lenet = "lenet"


app = FastAPI()


@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"}
Get the enumeration value
获取枚举值

You can get the actual value (a str in this case) using model_name.value, or in general, your_enum_member.value:

您可以使用 model_name.value 或通常使用 your_enum_member.value 来获取实际值(在这种情况下为 str):

from enum import Enum

from fastapi import FastAPI


class ModelName(str, Enum):
    alexnet = "alexnet"
    resnet = "resnet"
    lenet = "lenet"


app = FastAPI()


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

Tip

提示

You could also access the value "lenet" with ModelName.lenet.value.

您也可以通过 ModelName.lenet.value 获得『lenet』的值。

Return enumeration members
返回枚举成员

You can return enum members from your path operation, even nested in a JSON body (e.g. a dict).

您可以通过路径操作返回枚举成员,甚至可以嵌套在 JSON 主体(例如 dict)中。

They will be converted to their corresponding values before returning them to the client:

在将它们返回给客户端之前,它们将被转换为相应的值:

from enum import Enum

from fastapi import FastAPI


class ModelName(str, Enum):
    alexnet = "alexnet"
    resnet = "resnet"
    lenet = "lenet"


app = FastAPI()


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

Path parameters containing paths

包含路径的路径参数

Let’s say you have a path operation with a path /files/{file_path}.

假设您有一个路径操作,其路径为 /files/{file_path}

But you need file_path itself to contain a path, like home/johndoe/myfile.txt.

但是您需要 file_path 本身来包含一个路径,例如 home/johndoe/myfile.txt

So, the URL for that file would be something like: /files/home/johndoe/myfile.txt.

那么,该文件的 URL 将类似于:/files/home/johndoe/myfile.txt

OpenAPI support

OpenAPI 支持

OpenAPI doesn’t support a way to declare a path parameter to contain a path inside, as that could lead to scenarios that are difficult to test and define.

OpenAPI 不支持声明路径参数包含路径的方法,因为这可能导致难以测试和定义的方案。

Nevertheless, you can still do it in FastAPI, using one of the internal tools from Starlette.

不过,您仍然可以使用 Starlette 的内部工具在 FastAPI 中进行操作。

And the docs would still work, although not adding any documentation telling that the parameter should contain a path.

尽管交互式文档中不会添加任何该参数应包含路径的说明,但这些交互式文档仍然可以使用。

Path convertor

路径转换器

Using an option directly from Starlette you can declare a path parameter containing a path using a URL like:

通过使用直接来自 Starlette 的选项,您可以使用以下 URL 声明包含路径路径参数

/files/{file_path:path}

In this case, the name of the parameter is file_path, and the last part, :path, tells it that the parameter should match any path.

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

So, you can use it with:

因此,您可以将其用于:

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}

Tip

提示

You could need the parameter to contain /home/johndoe/myfile.txt, with a leading slash (/).

您可能需要参数为 /home/johndoe/myfile.txt,并另带有一个斜杠(/)开头。

In that case, the URL would be: /files//home/johndoe/myfile.txt, with a double slash (//) between files and home.

在这种情况下,URL为:/files//home/johndoe/myfile.txt,在 fileshome 之间使用双斜杠(//)。

Recap

回顾

With FastAPI, by using short, intuitive and standard Python type declarations, you get:

使用 FastAPI,通过使用简短、直观和标准的 Python 类型声明,您将获得:

  • Editor support: error checks, autocompletion, etc.

    编辑器支持:错误检查、自动完成等

  • Data “parsing”

    数据『解析』

  • Data validation

    数据验证

  • API annotation and automatic documentation

    API 批注和自动文档

And you only have to declare them once.

您只需要声明一次即可。

That’s probably the main visible advantage of FastAPI compared to alternative frameworks (apart from the raw performance).

与其他框架相比,这可能是 FastAPI 的主要可见优势(除了原始性能)。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值