Ste*_*veJ 9 python swagger fastapi
注意:这个问题与这里的问题不同,因为我需要它与 Swagger 一起工作。
给定一个 FastAPIGET端点,我希望允许任意一组 URL 参数,同时保持 Swagger 支持。
我的用例是我想要支持一组类似于 JSON API 的查询参数,如下所示:
/api/books/?include=author&sort=name,zip&sort[author]=-lname&fields=name,phone,street
Run Code Online (Sandbox Code Playgroud)
使用方括号使我无法使用传统的类来对查询参数进行建模,因此我直接使用该Request对象。但是,我想使用 Swagger 来测试端点。我找不到提供任意 URL 参数的方法。我很高兴将它们作为单个字符串输入。
人们可能会这样想:
def books(**params):
....
Run Code Online (Sandbox Code Playgroud)
这给出了一个curl语句:
api/books?params=sort%5Bone%5D%3Dtwo'
Run Code Online (Sandbox Code Playgroud)
我真正想要的是:
api/books?sort&one%5D%3Dtwo'
Run Code Online (Sandbox Code Playgroud)
您可以使用可选字符串参数(book_params在下面的情况中)通过 OpenAPI (Swagger UI) 将查询参数作为单个字符串传递,例如include=author&sort=name,zip&sort[author]=-lname&fields=name,phone,street. 然后,您可以解析查询数据(使用urllib.parse.parse_qs)来获取字典,如下所示。
下面的示例也利用此处描述的方法,以修复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"}。然而,下面的示例中演示的方法(使用上述方法)也通过解析查询字符串(可以使用 检索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)命名为唯一的名称,该参数也不会成为实际参数的一部分。
from fastapi import FastAPI, Request
from typing import Optional
from urllib.parse import parse_qs
app = FastAPI()
@app.get("/api/books")
def books(request: Request, book_params: Optional[str] = None):
q_params = {}
if book_params is not None:
q_params = parse_qs(book_params, keep_blank_values=True)
else:
q_params = parse_qs(request.url.query, keep_blank_values=True)
d = dict((k, v if len(v)>1 else v[0])
for k, v in q_params.items())
return d
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2946 次 |
| 最近记录: |