Загрузка файлов в FastAPI
FastAPI предоставляетFileиUploadFileДва способа обработки загрузки файлов: поддержка загрузки отдельных файлов и смешанной загрузки форм и файлов.
Установите зависимости
Загрузка файлов также зависит отpython-multipart:
pip install python-multipart
Использование UploadFile
UploadFileявляется рекомендуемым подходом, он предоставляет более богатый интерфейс для доступа к информации о файле:
Пример
app = FastAPI()
@app.post("/uploadfile/")
async def create_upload_file(file: Upload):
# Свойства и методы, предоставляемые Upload
return {
"filename": file.filename, # Имя файла
"content_type": file.content_type, # MIME-тип файла
"size": file.size, # Размер файла (в байтах)
}
UploadFileСвойства и методы:
| Атрибуты/Методы | Type | Описание |
|---|---|---|
filename | str | None | Исходное имя загруженного файла |
content_type | str | None | MIME-тип файла (например,image/png) |
file | SpooledTemporaryFile | Файлоподобный объект, который может читать содержимое файла |
size | int | None | Размер файла (в байтах) |
read() | Методы | Читать содержимое файла какbytes |
write() | Методы | Записать содержимое в файл |
seek() | Методы | Переместить позицию указателя файла |
close() | Методы | Закрытие файла |
UploadFileИспользует "SpooledTemporaryFile" для хранения содержимого файла. Когда файл небольшой, он хранится в памяти; когда файл большой, он автоматически записывается на диск, поэтому это болееbytesБолее экономично по памяти.
Используйте File для получения содержимого файла
FileНепосредственно читать содержимое файла какbytes, подходит для небольших файлов:
Пример
app = FastAPI()
@app.post("/files/")
async def create_file(file: bytes = File()):
# file — это необработанные байтовые данные файла
return {"file_size": len(file)}
FileиUploadFileсравнение:
| Пункт сравнения | File | UploadFile |
|---|---|---|
| Типы данных | bytes | Объект File |
| Использование памяти | Загрузить весь файл в память | Большие файлы автоматически записываются на диск |
| Информация о файле | Нет (только содержимое) | Есть имя файла, тип, размер |
| Применимые сценарии | небольшой файл | Сценарии с большими файлами или когда нужна информация о файле |
Необязательная загрузка файла
Использовать значение по умолчаниюNoneСделать загрузку файла необязательной:
Пример
app = FastAPI()
@app.post("/uploadfile/")
async def create_upload_file(file: UploadFile | None = Отсутствует):
if not file:
return {"message": "Файл не загружен"}
return {"filename": file.filename}
Загрузка нескольких файлов
Используйте список для получения нескольких файлов:
Пример
app = FastAPI()
@app.post("/uploadfiles/")
async def create_upload_files(files: list[UploadFile]):
return {"filenames": [file.filename for file in files]}
Смешанная загрузка формы и файла
Вы можете одновременно получать данные формы и файлы в одном маршруте:
Пример
app = FastAPI()
@app.post("/items/")
async def create_item(
# Поля формы
name: str = Form(...),
description: str | None = Form(None),
# Загрузка файла
file: UploadFile | None = None,
):
result = {"name": name, "description": description}
if file:
result["filename"] = file.filename
return result
Сохранить загруженный файл
Следующий пример показывает, как сохранять загруженные файлы на диск:
Пример
from fastapi import FastAPI, UploadFile
app = FastAPI()
@app.post("/uploadfile/")
async def create_upload_file(file: Upload):
# Сохранить загруженный файл по указанному пути
with open(f"uploads/{file.filename}", "wb") as buffer:
shutil.copyfileobj(file.file, buffer)
return {"filename": file.filename, "message": "Файл успешно загружен"}
В реальных проектах при загрузке файлов обратите внимание: 1) Проверяйте тип и размер файла; 2) Используйте безопасные имена файлов (избегайте атак с обходом пути); 3) Ограничьте права на каталог загрузки; 4) Для больших файлов используйте потоковую передачу вместо чтения всего сразу.
Итог
- Рекомендуется
UploadFile, это экономит больше памяти и предоставляет расширенную информацию о файле FileПодходит для сценариев с небольшими файлами, читается напрямую какbytes- Использование
list[UploadFile]Получение нескольких загружаемых файлов - form (
Form) и file (UploadFile) можно использовать в одном и том же маршруте - Обратите внимание на безопасность при загрузке файлов: проверяйте типы файлов, используйте безопасные имена файлов и ограничивайте размеры