Note that the answer below uses synchronous writing for writing the files to disk. If you need async writing, please have a look at this answer. Moreover, if you need to send additional data (such as JSON data) together with uploading the file(s), please have a look at this answer. I would suggest you have a look at this answer as well, which explains the difference between defining an endpoint with def and async def, and demonstrates how to read the contents of an uploaded file when using def (if that's a requirement for your app).
Upload Single File
app.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)
test.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())
Upload Multiple (List of) Files
app.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)
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())