使用 FastAPI 解析来自 Slack 的传入 POST 请求

Pil*_*hae 4 python slack-api slack slack-commands fastapi

我正在构建一个 FastAPI 服务器来接收 slacklash 命令发送的请求。使用下面的代码,我可以看到以下内容:

token=BLAHBLAH&team_id=BLAHBLAH&team_domain=myteam&channel_id=BLAHBLAH&channel_name=testme&user_id=BLAH&user_name=myname&command=%2Fwhatever&text=test&api_app_id=BLAHBLAH&is_enterprise_install=false&response_url=https%3A%2F%2Fhooks.slack.com%2Fcommands%BLAHBLAH&trigger_id=BLAHBLAHBLAH
Run Code Online (Sandbox Code Playgroud)

被打印出来,这正是我在官方文档中看到的有效负载。我正在尝试使用有效负载信息来做某事,我很好奇是否有一种解析此有效负载信息的好方法。我绝对可以使用 split 函数或任何其他漂亮的函数来解析这个有效负载,但我很好奇是否有一种“事实上的”方法来处理松弛有效负载。提前致谢!

from fastapi import FastAPI, Request

app = FastAPI()

@app.post("/")
async def root(request: Request):
    request_body = await request.body()
    print(request_body)
Run Code Online (Sandbox Code Playgroud)

Chr*_*ris 9

接收JSON数据

\n

您通常会使用Pydantic 模型来声明请求主体\xe2\x80\x94(如果您要接收格式为 \xe2\x80\x94 的数据),从而受益于PydanticJSON必须提供的自动验证(有关如何发布数据的更多选项) ,看看这个答案)。因此,您必须定义这样的模型:JSON

\n
from pydantic import BaseModel\n\nclass Item(BaseModel):\n    token: str\n    team_id: str\n    team_domain: str\n    # etc.\n\n@app.post("/")\ndef root(item: Item):\n    print(item.dict())  # convert to dictionary (if required)\n    return item\n
Run Code Online (Sandbox Code Playgroud)\n

有效负载如下所示:

\n
{\n    "token": "gIkuvaNzQIHg97ATvDxqgjtO"\n    "team_id": "Foo",\n    "team_domain": "bar",\n    # etc.\n}\n
Run Code Online (Sandbox Code Playgroud)\n

接收Form数据

\n

但是,如果您要接收作为Formdata 的有效负载,就像 slack API 所做的那样(如您提供的链接中所示),您可以使用Formfields. 对于Form字段,您的有效负载仍将根据这些字段以及您定义它们的类型进行验证。但是,您需要定义端点中的所有参数,如上面的链接所述,如下所示:

\n
from fastapi import  Form\n\n@app.post("/")\ndef root(token: str = Form(...), team_id: str = Form(...), team_domain: str = Form(...)):\n    return {"token": token, "team_id": team_id, "team_domain": team_domain}\n
Run Code Online (Sandbox Code Playgroud)\n

或者为了避免在端点中指定参数,如果您有大量Form字段,您可以创建一个自定义依赖类(为了简单起见,使用装饰器),这将允许您在单独的类中@dataclass定义多个字段,并且Form仅在端点\xe2\x80\x94中使用该类定义,请参阅此答案此答案以获取有关 FastAPI 依赖项的更多详细信息。例子:

\n
from dataclasses import dataclass\nfrom fastapi import FastAPI, Form, Depends\n\n@dataclass\nclass Item:\n    token: str = Form(...)\n    team_id: str = Form(...)\n    team_domain: str = Form(...)\n    #...\n\n@app.post("/")\ndef root(data: Item = Depends()):\n    return data\n
Run Code Online (Sandbox Code Playgroud)\n

由于 FastAPI 实际上是 Starlette 的底层,即使您仍然必须按照问题中的方式访问请求正文,您也应该使用诸如request.json()或 之类的方法,request.form()Starlette 文档中所述,这将允许您获取请求正文分别解析为JSONform-data。请查看此答案此答案以获取更多详细信息和示例。

\n