我正在尝试提出一个
POST
请求:
import requests
files = {'template': open('template.xlsx', 'rb')}
payload = {
'context': {
'OUT': 'csv',
'SHORT': 'short'
},
'filename': 'file.xlsx',
'content_type': 'application/excel'
}
r = requests.post('http://localhost:8000/render', files=files, data=payload)
到 FastAPI 服务器:
from fastapi import FastAPI, UploadFile, Form
from pydantic import Json
app = FastAPI()
@app.post('/render')
def render(template: UploadFile, context: Json = Form(), filename: str = Form(...), content_type: str = Form(...)):
# processing
return "ok"
但是我得到这个错误(
422
状态代码):
{"detail":[{"loc":["body","context"],"msg":"Invalid JSON","type":"value_error.json"}]}
如您所见,我正在尝试同时通过
file
和 request body
。我想如果将 payload['context']
转换为 JSON 我可以解决这个问题。但我想在服务器端解决这个问题。
如何修复错误?也许在参数传递到视图之前转换一些或类似的东西?
json.dumps()
在客户端序列化您的 JSON。此外,您实际上不需要发送元数据,例如 filename
和 content_type
作为 JSON 负载的一部分。您可以在multipart-encoded file中明确设置
filename
(您可以自定义)和content_type
,稍后您可以使用UploadFile
属性在服务器端检索。此外,content_type
(或mime type
)文件的.xlsx
不应该是application/excel
,但是,如here和here所述,应该是application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
。最后,我还建议你看看这个答案,它解释了你不能同时拥有form-data
/files
和JSON
的原因,并提供了允许一个人的解决方案提交两者,并验证 JSON 数据——在您的情况下,JSON 数据未针对 Pydantic 模型进行验证,这意味着客户端可以发送任何类型的数据或省略任何 required
属性。
app.py
from fastapi import FastAPI, UploadFile, Form, File
from pydantic import Json
app = FastAPI()
@app.post('/render')
def render(file: UploadFile = File(...), context: Json = Form()):
print(context, context['OUT'], file.filename, file.content_type, sep="\n")
return "ok"
test.py
import requests
import json
url = 'http://localhost:8000/render'
files = {'file': ('file.xlsx', open('template.xlsx', 'rb'), 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')}
payload = {'context': json.dumps({'OUT': 'csv','SHORT': 'short'})}
r = requests.post(url, files=files, data=payload)
print(r.json())