如何使用FastAPI中的Request对象获取文件和表单数据?

问题描述 投票:0回答:1

我正在开发一个 webhook,其中第三方服务将访问我的 URL 并提供一些文件,现在我无法使用 FastAPI 的

UploadFile = File (...)
,因为它会引发必填字段 File 的错误 我想从请求对象中读取有效负载和文件,就像我们在 Flask 中所做的那样,只需这样做

from flask import request
files = request.files

如何在 FastAPI 中实现相同的效果?

python file fastapi webhooks starlette
1个回答
1
投票

您可以使用 Starlette 的

request.form()
方法来解析正文,这将返回一个
FormData
对象,其中包含文件上传和文本输入。有关更多详细信息和参考,请查看这个答案,以下示例基于该答案。另一种解决方案是使用此答案的选项 1 中演示的方法。

此外,如果出于任何原因,您想使用

def
而不是
async def
端点,请查看 这个答案,了解如何读取
def
端点内的文件内容。您可能会发现这个答案也很有帮助。

工作示例

app.py

from fastapi import FastAPI, Depends, Request, HTTPException
from starlette.datastructures import FormData

app = FastAPI()

async def get_body(request: Request):
    content_type = request.headers.get('Content-Type')
    if content_type is None:
        raise HTTPException(status_code=400, detail='No Content-Type provided!')
    elif (content_type == 'application/x-www-form-urlencoded' or
          content_type.startswith('multipart/form-data')):
        try:
            return await request.form()
        except Exception:
            raise HTTPException(status_code=400, detail='Invalid Form data')
    else:
        raise HTTPException(status_code=400, detail='Content-Type not supported!')


@app.post('/')
async def main(body = Depends(get_body)):
    if isinstance(body, FormData):  # if Form/File data received
        msg = body.get('msg')
        items = body.getlist('items')
        files = body.getlist('files')  # returns a list of UploadFile objects
        if files:
            for file in files:
                print(f'Filename: {file.filename}. Content (first 15 bytes): {await file.read(15)}')
        return 'OK'

测试.py

import requests

url = 'http://127.0.0.1:8000/'
data = {'items': ['foo', 'bar'], 'msg': 'Hello!'}
files = [('files', open('a.txt', 'rb')), ('files', open('b.txt', 'rb'))]
 
# Send Form data and files
r = requests.post(url, data=data, files=files)  
print(r.text)

# Send Form data only
r = requests.post(url, data=data)              
print(r.text)
© www.soinside.com 2019 - 2024. All rights reserved.