[英]How to Upload File using FastAPI?
我正在使用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 庫發送請求時,如下圖所示:
f = open(".../file.txt", 'rb')
files = {"file": (f.name, f, "multipart/form-data")}
requests.post(url="SERVER_URL/create_file", files=files)
file2store
變量始終為空。 有時(很少見),它可以獲取文件字節,但幾乎所有時間它都是空的,所以我無法恢復其他數據庫上的文件。
我也嘗試了bytes
而不是UploadFile
,但我得到了相同的結果。 我的代碼有問題,還是我使用 FastAPI 上傳文件的方式有誤?
請注意,下面的答案使用同步寫入將文件寫入磁盤。 如果您需要異步寫作,請查看此答案。 此外,如果您需要在上傳文件的同時發送其他數據(例如JSON
數據),請查看此答案。 我建議您也看看這個答案,它解釋了使用def
和async def
定義端點之間的區別,並演示了如何在使用def
時讀取上傳文件的contents
(如果這是您的應用程序的要求) .
應用程序.py
import uvicorn
from fastapi import File, UploadFile, FastAPI
app = FastAPI()
@app.post("/upload")
async def upload(file: UploadFile = File(...)):
try:
contents = await file.read()
with open(file.filename, 'wb') as f:
f.write(contents)
except Exception:
return {"message": "There was an error uploading the file"}
finally:
await file.close()
return {"message": f"Successfuly uploaded {file.filename}"}
if __name__ == '__main__':
uvicorn.run(app, host='0.0.0.0', port=8000)
測試.py
import requests
url = 'http://127.0.0.1:8000/upload'
file = {'file': open('images/1.png', 'rb')}
resp = requests.post(url=url, files=file)
print(resp.json())
應用程序.py
import uvicorn
from fastapi import File, UploadFile, FastAPI
from typing import List
app = FastAPI()
@app.post("/upload")
async def upload(files: List[UploadFile] = File(...)):
for file in files:
try:
contents = await file.read()
with open(file.filename, 'wb') as f:
f.write(contents)
except Exception:
return {"message": "There was an error uploading the file(s)"}
finally:
await file.close()
return {"message": f"Successfuly uploaded {[file.filename for file in files]}"}
if __name__ == '__main__':
uvicorn.run(app, host='0.0.0.0', port=8000)
測試.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())
@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}
只需復制並粘貼代碼即可完美運行。
from fastapi import (
FastAPI
UploadFile,
File,
status
)
from fastapi.responses import JSONResponse
import aiofiles
app = FastAPI( debug = True )
@app.post("/upload_file/", response_description="", response_model = "")
async def result(file:UploadFile = File(...)):
try:
async with aiofiles.open(file.filename, 'wb') as out_file:
content = await file.read() # async read
await out_file.write(content) # async write
except Exception as e:
return JSONResponse(
status_code = status.HTTP_400_BAD_REQUEST,
content = { 'message' : str(e) }
)
else:
return JSONResponse(
status_code = status.HTTP_200_OK,
content = {"result":'result'}
)
我已經工作了將近 7-8 個月前,我沒有遇到你說的問題。 我發現UploadFile是SpooledTemproaryFile類型,我沒有嘗試異步讀取文件。 這是正在使用的代碼段。 我已經上傳了所有類型的文件,最大 100mb,它正在工作。 我必須將文件保存在特定路徑上的服務器上
with open(path, 'wb') as f:
[f.write(chunk) for chunk in iter(lambda: file.file.read(10000), b'')]
在您的情況下,我建議直接使用aiohttp會話或來自httpx的AsyncClient讀取文件並發出發布請求
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.