当前位置: 首页 > 知识库问答 >
问题:

使用带有文件和查询参数的Python请求向FastAPI发送POST请求

桑思远
2023-03-14

我正在使用FastAPI来提供一些ML模型,并且我有一个使用Python Requests模块的Streamlit基本UI。

我的服务之一是通过POST请求获得图像,它就像一个魅力。

服务器端

@app.post("/segformer")
async def segformer(file: Optional[UploadFile] = None):

{BASE_URI}/docs提供的卷曲

curl -X 'POST' \
  'http://localhost:8080/segformer' \
  -H 'accept: application/json' \
  -H 'Content-Type: multipart/form-data' \
  -F 'file=@image1.jpg;type=image/jpeg'

客户端使用Python请求

response = requests.post(f"{BASE_URI}/segformer", files=files)

一旦我想添加额外的参数,它就变得令人毛骨悚然。例如:

服务器端

@dataclass
class ModelInterface:
    model_name: str = "detr"
    tags: List[str] = Query(...)

@app.post("/detr")
async def detr(file: UploadFile = File(...), model: ModelInterface = Depends()):

curl -- 由 {BASE_URI}/docs 给出

curl -X 'POST' \
  'http://localhost:8080/detr?model_name=detr&tags=balloon&tags=dog' \
  -H 'accept: application/json' \
  -H 'Content-Type: multipart/form-data' \
  -F 'file=@image1.jpg;type=image/jpeg'

在那之前,一切正常。一旦我想使用Python<code>Requests</code>转换该调用,我就会遇到一些问题,最终总是出现<code>/detr HTTP/1.1“400 Bad Request</code>错误。

以下是我尝试过的:

客户端使用Python请求

headers = {
    "Content-type": "multipart/form-data",
    "accept": "application/json"
}

payload = {
    "tags": ["balloon", "dog"]
}

response = requests.post(
    f"{BASE_URI}/detr",
    headers=headers,
    json=payload,  <- also *data*  
    files=files,
)

最后,问题似乎缩小了如何转换它:

curl -X 'POST' \
  'http://localhost:8080/detr?tags=balloon&tags=dog' \
  -H 'accept: application/json' \
  -H 'Content-Type: multipart/form-data' \
  -F 'file=@image1.jpg;type=image/jpeg'

到有效的Python请求调用!

我还遇到了以下FastAPI代码的问题:

@dataclass
class ModelInterface:
    model_name: str = "detr"
    tags: List[str] = None

@app.post("/detr2")
async def detr2(file: UploadFile = File(...), model: ModelInterface = Form(...)):
...

转换为curl命令:

curl -X 'POST' \
  'http://localhost:8080/detr2' \
  -H 'accept: application/json' \
  -H 'Content-Type: multipart/form-data' \
  -F 'file=@image1.jpg;type=image/jpeg' \
  -F 'model={
  "model_name": "detr",
  "tags": [
    "balloon", "dog"
  ]
}' 

失败,出现“POST/det2 HTTP/1.1”422不可处理实体错误

共有1个答案

贺兴昌
2023-03-14

要在Python请求中传递查询参数,应该使用< code>params键。因此:

response = requests.post(url='<your_url_here>', params=payload)

此外,不需要在头中设置< code>Content-type,因为它会根据传递给< code>requests.post()的参数自动添加。这样做,请求将失败,因为除了< code>multipart/form-data之外,“< code>Content-type必须包括用于描述post主体中各部分的< code>boundary值。不设置< code>Content-Type头可确保requests将其设置为正确的值”(ref)。看看这个和这个。此外,请确保在< code>files中使用您在endpoint中给出的相同< code>key名称,即< code>file。因此,在Python请求中,它应该如下所示:

files = {('file', open('my_file.txt', 'rb'))}
response = requests.post(url='<your_url_here>', files=files, params=payload)

您还可以在此答案中找到有关如何发送其他数据以及文件的更多选项。

 类似资料:
  • 单击from-data或x-www-form-urlencoded 然后在键/值字段上传递两个参数。 ANDROID改装设置 原因是我使用了2个API(webapi和wcf)。我的所有其他响应都是对象数组。[{},{}]但在此呼叫中,我收到了以下信息 但我还是无法解析响应。

  • 我们公司有一个基于.NET的网站 几天前,我们向网站程序员请求一个webservice。昨天他给了我一个URL 当我从localhost打开URL时,它显示了一个页面,我可以从我们请求编程的四个方法(函数)中选择一个。 通过选择其中一个,一个新的页面显示如下: SOAP 1.1 以下是SOAP 1.1请求和响应示例。显示的占位符需要用实际值替换。 POST/webservices/findstat

  • 请求方式: "|3|2|url,content|\r" 参数: url 设置Post请求的url链接 content post请求的数据 返回值: "|3|code|data|\r" 参数: code http请求返回的成功或者错误码 成功:code = 200 获取数据失败:code = -1 http请求字段错误:code = 1 data http请求返回的数据 Arduino样例: sof

  • 问题内容: 这是对API调用的原始请求: 该请求返回成功(2xx)响应。 现在,我尝试使用发送此请求: 一切对我来说看起来不错,我不太确定自己张贴的错误是什么导致400响应。 问题答案: 用于GET样式的URL参数,用于POST样式的正文信息。在请求中 同时 提供 两种 类型的信息是完全合法的,您的请求也可以这样做,但是您已经将URL参数编码为URL。 您的原始帖子虽然包含 JSON 数据。可以为

  • 问题内容: 是否可以使用Python的库发送SOAP请求? 问题答案: 确实有可能。 这是一个使用普通请求lib调用Weather SOAP Service的示例: 一些注意事项: 标头很重要。没有正确的标头,大多数SOAP请求将无法工作。可能是更 正确 使用的标头(但weatherservice更喜欢 这将以xml字符串形式返回响应-然后,您需要解析该xml。 为简单起见,我以纯文本形式包含了该