如何在 FastAPI 中接收图像和 json 数据?

How do I receive image and json data in FastAPI?

我正在通过以下方式将图像和 json 数据发送到我的 API:

import requests
filename = "test_image.jpeg"
files = {'my_file': (filename, open(filename, 'rb'))}
json={'first': "Hello", 'second': "World"}

response = requests.post('http://127.0.0.1:8000/file', files=files, params=json)

如何通过 FastAPI 在服务器端接收图像和 json 数据?

我的代码如下所示:

@app.post('/file')
def _file_upload(my_file: UploadFile = File(...), params: str = Form(...)):

    image_bytes = my_file.file.read()
    decoded = cv2.imdecode(np.frombuffer(image_bytes, np.uint8), -1)
    pg_image = cv2.resize(decoded, (220, 220))
    return {"file_size": params}

但是,这给了我以下错误:

<Response [422]>
{'detail': [{'loc': ['body', 'params'], 'msg': 'field required', 'type': 'value_error.missing'}]}

我这里有什么地方做错了吗?

我认为您在这里遗漏了一个非常基本的观点。

@app.post('/file')
def my_function(param1: str,  param2: str):
    ...

假设你有上面的代码,它期望的请求体必须是这种格式。

{"param1": "some string", "param2": "some_string"}

请求正文的键应该匹配您的端点参数。否则,它会抛出错误。

假设您要发送此请求正文

{'first': "Hello", 'second': "World"}

这会起作用。

@app.post("/dummy")
def my_function(first: str = Body(...), second: str = Body(...)):
    ...

这会失败

@app.post('/file')
def my_function(param1: str = Body(...),  param2: str = Body(...)):
    ...

在您的示例中,/file 端点的函数在请求正文中需要两件事,my_fileparams 但您发送的是 {'first': "Hello", 'second': "World"} 而不是 params。这就是它引发错误的原因。

您必须将路由器函数中期望的参数定义为,

# app.py
from fastapi import FastAPI, File, UploadFile, Form

app = FastAPI()


@app.post('/file')
def _file_upload(
        my_file: UploadFile = File(...),
        <b>first: str = Form(...),
        second: str = Form("default value  for second"),</b>
):
    return {
        "name": my_file.filename,
        "first": first,
        "second": second
    }
# client.py
import requests

filename = "requirements.txt"
files = {'my_file': (filename, open(filename, 'rb'))}
json = {'first': "Hello", 'second': "World"}

response = requests.post(
    'http://127.0.0.1:8000/file',
    files=files,
    <b>data={'first': "Hello", 'second': "World"}</b>
)
print(response.json())

当我遇到同样的问题时,我遇到了你的问题。我一直在寻找一种方法可以让我的端点接受 JSON 正文和文件(图像)。答案是你不能。

这是因为它们都需要不同的内容类型,我认为在发出请求时没有办法设置 2 内容类型。

我在打开文档时注意到了这一点。设置为允许图像的内容类型是不接受 JSON 的原因。这就是您的程序抛出错误,指出缺少这些字段的原因。

但是,您可以按照其他评论的建议,使用表格在 JSON 正文中输入您需要的所有参数。它应该可以正常工作,因为这些值仍然可以被接受。

但对我来说,我选择使用端点来接受没有图像的 JSON 并为对象提供默认图像。然后我创建了另一个端点来更新图像。