【问题标题】:How to Upload File using FastAPI?使用 fastapi 上传文件
【发布时间】:2020-11-12 20:36:55
【问题描述】:

我正在使用fastapi按照官方文档上传文件,就像:

@app.post("/create_file/")
async def create_file(file: UploadFile=File(...)):
      file2store = await file.read()
      # some code to store the BytesIO(file2store) to the other database

当我使用 python requests lib 发送请求时:

f = open(".../file.txt", 'rb')
files = {"file": (f.name, f, "multipart/form-data")}
requests.post(url="SERVER_URL/create_file", files=files)

file2store 始终为空。有时(很少见),它可以获取文件字节,但几乎所有时间它都是空的,所以我无法恢复其他数据库上的文件。 我也尝试了“字节”而不是“上传文件”,我得到了相同的结果。 我的代码是否有问题,或者我使用fastapi上传文件的方式错误?我谷歌了很长时间的一些答案,但失败了。所以我在这里提出这个问题,希望知道答案的人可以帮助我。谢谢

【问题讨论】:

  • 您是否安装了python-multipart?如果不是pip install python-multipart
  • 是的,我已经安装了。有时我可以上传成功,但这种情况很少发生。
  • 是否发生在特定的文件类型上?
  • 我试过 docx, txt, yaml, png 文件,它们都有同样的问题。而且我刚发现第一次上传新文件的时候可以上传成功,但是第二次(或者更多次)上传就失败了。
  • 我知道原因。谢谢你启发我。我只使用了一次f = open(file)方法,当我多次发送请求时,第一次之后f会被关闭。再次感谢您帮助我。

标签: python file-upload fastapi


【解决方案1】:
@app.post("/create_file/")
async def image(image: UploadFile = File(...)):
    print(image.file)
    # print('../'+os.path.isdir(os.getcwd()+"images"),"*************")
    try:
        os.mkdir("images")
        print(os.getcwd())
    except Exception as e:
        print(e) 
    file_name = os.getcwd()+"/images/"+image.filename.replace(" ", "-")
    with open(file_name,'wb+') as f:
        f.write(image.file.read())
        f.close()
   file = jsonable_encoder({"imagePath":file_name})
   new_image = await add_image(file)
   return {"filename": new_image}

【讨论】:

  • 请说明您的代码如何解决问题。
【解决方案2】:

原答案是here。请注意,下面的答案使用 同步写入 将文件写入磁盘。如果您需要异步编写,请查看aiofiles 和答案here

app.py

import uvicorn
from fastapi import File, UploadFile, FastAPI
from typing import List

app = FastAPI()


def save_file(filename, data):
    with open(filename, 'wb') as f:
        f.write(data)

@app.post("/upload")
async def upload(files: List[UploadFile] = File(...)):

    # in case you need the files saved, once they are uploaded
    for file in files:
        contents = await file.read()
        save_file(file.filename, contents)

    return {"Uploaded Filenames": [file.filename for file in files]}
    

if __name__ == '__main__':
    uvicorn.run(app, host='127.0.0.1', port=8000, debug=True)

test.py

import requests

url = 'http://127.0.0.1:8000/upload'
files = [('files', open('images/1.png', 'rb')), ('files', open('images/2.png', 'rb'))]
resp = requests.post(url=url, files = files) 
print(resp.json())

【讨论】:

    【解决方案3】:

    我已经工作了将近 7-8 个月前,我没有遇到您所说的问题。 我发现 UploadFile 的类型是 SpooledTemproaryFile 并且我没有尝试异步读取文件。这是正在使用的sn-p。我已经上传了所有类型的文件,最大 100mb,它正在工作。我必须将文件保存在特定路径上的服务器上

    with open(path, 'wb') as f:
        [f.write(chunk) for chunk in iter(lambda: file.file.read(10000), b'')]
    

    在您的情况下,我建议您直接使用 aiohttp 会话或 AsyncClienthttpx

    读取文件并发出发布请求

    【讨论】:

      猜你喜欢
      • 2021-04-19
      • 2021-10-20
      • 1970-01-01
      • 2022-07-24
      • 1970-01-01
      • 1970-01-01
      • 2021-11-01
      • 1970-01-01
      • 2023-01-31
      相关资源
      最近更新 更多