注意:此问题与here问题不同,因为我需要它来处理Swagger。
给定一个FastAPI GET
端点,我希望允许任意的URL参数集,同时保持对Swagger的支持。
我的用例是希望支持一组类似JSON API的查询参数,如下所示:
/api/books/?include=author&sort=name,zip&sort[author]=-lname&fields=name,phone,street
方括号的使用使我无法使用传统的类来建模查询参数,所以我直接使用Request
对象来代替。然而,我想使用Swagger来测试端点。我找不到一种方法来提供任意的URL参数。我很乐意将它们作为单个字符串键入。
人们可能会这样想:
def books(**params):
....
这给出了一个curl语句:
api/books?params=sort%5Bone%5D%3Dtwo'
我真正想要是:
api/books?sort&one%5D%3Dtwo'
1条答案
按热度按时间puruo6ea1#
您可以使用可选字符串参数(在下面的示例中为
book_params
)通过OpenAPI(Swagger UI)将查询参数作为单个字符串传递,例如include=author&sort=name,zip&sort[author]=-lname&fields=name,phone,street
。然后,您可以解析查询数据(使用urllib.parse.parse_qs
)以获得字典,如下所示。下面的例子也使用了here描述的方法,以便修复
parse_qs
将单个值解析为列表的部分(例如,'foo=bar'
将被解析为foo = ['bar']
),同时还保留用户传递给列表的键的所有值。例如,如果用户在URL中多次传递相同的键,即,例如,'foo=2&bar=7&foo=10'
,则使用dict(request.query_params)
检索查询参数将得到{"foo":"10","bar":"7"}
而不是{"foo":["2","10"],"bar":"7"}
。但是,下面的示例中演示的方法(使用上述方法)也处理了这一问题,方法是解析query string(可以使用request.url.query
检索),并确保保留实际列表。可以通过检查这个可选参数
book_params
是否为空,来决定是否使用book_params
读取查询参数(意味着请求通过Swagger发送)或直接使用Request
对象(意味着通过在浏览器的地址栏中键入URL来发送请求,例如http://127.0.0.1:8000/api/books?include=author&sort=name,zip&sort[author]=-lname&fields=name,phone,street
,或者使用其他客户端应用程序)。请确保为该可选参数(例如book_params
)命名为唯一的名称,该名称不会也是实际参数的一部分。