如何根据FastApi中的另一个查询参数使查询参数成为必需?

时间:2019-04-07 04:49:33

标签: python api

我想根据FastApi

中的另一个查询参数来使查询参数成为必需

例如,我有四个查询参数:commandstart_dateend_dateincrement

如果command等于“ analyse”,则必须输入end_date。但是,如果command等于“ add_working_days”,则不需要end_date,但需要increment。这可能吗?

这是我现在的代码权限:

import datetime
from fastapi import FastAPI, Query

app = FastAPI()  

@app.get("/api/")
async def read_item(
    start_date: str = Query(..., regex=r"[\d]{4}-[\d]{1,2}-[\d]{1,2}"),
    end_date: str = Query(..., regex=r"[\d]{4}-[\d]{1,2}-[\d]{1,2}"),
    command: str = None,
    increment: int = None,
):
    parsed_start_date = datetime.datetime.strptime(start_date, "%Y-%m-%d")
    parsed_end_date = datetime.datetime.strptime(end_date, "%Y-%m-%d")
    duration = parsed_end_date - parsed_start_date
    return duration.days

2 个答案:

答案 0 :(得分:2)

如果按照建议的方式编写,可能会想做。您可以将默认值None设置为参数,以提供一些灵活性并验证规则,例如:

If command == analyse:
  Check start_date is valid
  Check end_date is also valid
  Check increment is None

If command == add_working_days:
  Check start_date is valid
  Check end_date is None
  Check increment is also valid

但是我认为这不是您想要做的正确方法。

在上述情况下,FastAPI无法生成用于在GUI中表达参数组合的文档(例如https://petstore.swagger.io/


我的看法是

对于任何API使用者而言,此类文档都是您的产品。 他们不清楚应该将哪些参数组合一起传递。 您将需要在说明中提供诸如自由文本之类的文档。

由于创建了Open API规范是为了帮助开发人员尽快了解彼此,因此我建议您遵守该规范,并避免这种规则组合。

从Open API规范派生的FastAPI语法将无法描述基于您选择传递的参数将代码的行为路由到其他函数的URL。

也许,也许,也许这是Java,也许Swagger之类的工具可以支持您的代码,因为可以为同一个函数名编写多个签名,但是由于这是Python,因此我认为这不是可行的行为。

- 我的建议

按照NguyễnNhân的回答。正如他的建议,将不同的URL和参数组合描述为单独的路由器方法。这将使您无需设计复杂的IF。这将向您的用户说明他们必须传递此类参数。


免责声明

以上所有都是我认为正确的方法。其他人可能不同意。如果我不得不考虑使用一个URL来完成所有操作的情况,那么每个可选参数都会增加预期的功能,并且依赖于任何其他参数。 >

例如:

domain/maps?location=XYZ&
add_markers: boolean
add_traffic: boolean
language: [EN,HE]

可能的链接

domain/maps?location=XYZ&add_markers=true&add_traffic=true&language=EN
domain/maps?location=XYZ&add_traffic=true&language=HE
domain/maps?location=XYZ&add_markers=true

等,其中每个传递的参数彼此独立。

答案 1 :(得分:1)

我建议分开您的api

import datetime
from fastapi import FastAPI, Query

app = FastAPI()  

@app.get("/api/analyse")
async def read_item_for_analyse(
    start_date: str = Query(..., regex=r"[\d]{4}-[\d]{1,2}-[\d]{1,2}"),
    end_date: str = Query(..., regex=r"[\d]{4}-[\d]{1,2}-[\d]{1,2}"),
    increment: int = None,
):
    # do something 

@app.get("/api/add_working_days")
async def read_item_for_add_working_days(
    start_date: str = Query(..., regex=r"[\d]{4}-[\d]{1,2}-[\d]{1,2}"),
    end_date: str = None,
    increment: int = Query(..., title="Increase working days"),
):
    # do something 

它清晰易懂,或者继续您的风格并添加一些“如果...其他”就足够了。