11 KiB
Запит файлів
Ви можете визначити файли, які будуть завантажуватися клієнтом, використовуючи File.
/// info | Інформація
Щоб отримувати завантажені файли, спочатку встановіть python-multipart.
Переконайтеся, що ви створили віртуальне середовище{.internal-link target=_blank}, активували його, а потім встановили пакет, наприклад:
$ pip install python-multipart
Це необхідно, оскільки завантажені файли передаються у вигляді «form data».
///
Імпорт File
Імпортуйте File та UploadFile з fastapi:
{* ../../docs_src/request_files/tutorial001_an_py39.py hl[3] *}
Визначення параметрів File
Створіть параметри файлів так само як ви б створювали Body або Form:
{* ../../docs_src/request_files/tutorial001_an_py39.py hl[9] *}
/// info | Інформація
File — це клас, який безпосередньо успадковує Form.
Але пам’ятайте, що коли ви імпортуєте Query, Path, File та інші з fastapi, це насправді функції, які повертають спеціальні класи.
///
/// tip | Порада
Щоб оголосити тіла файлів, вам потрібно використовувати File, тому що інакше параметри будуть інтерпретовані як параметри запиту або параметри тіла (JSON).
///
Файли будуть завантажені у вигляді «form data».
Якщо ви оголосите тип параметра функції операції шляху як bytes, FastAPI прочитає файл за вас, і ви отримаєте його вміст у вигляді bytes.
Майте на увазі, що це означає, що весь вміст буде збережено в пам'яті. Це працюватиме добре для малих файлів.
Але є кілька випадків, у яких вам може бути корисно використовувати UploadFile.
Параметри файлу з UploadFile
Визначте параметр файлу з типом UploadFile:
{* ../../docs_src/request_files/tutorial001_an_py39.py hl[14] *}
Використання UploadFile має кілька переваг перед bytes:
- Вам не потрібно використовувати
File()у значенні за замовчуванням параметра. - Використовується «spooled» файл:
- Файл зберігається в пам'яті до досягнення максимального обмеження розміру, після чого він буде збережений на диску.
- Це означає, що він добре працюватиме для великих файлів, таких як зображення, відео, великі двійкові файли тощо, не споживаючи всю пам'ять.
- Ви можете отримати метадані про завантажений файл.
- Він має file-like
asyncінтерфейс. - Він надає фактичний об'єкт Python
SpooledTemporaryFile, який можна передавати безпосередньо іншим бібліотекам, що очікують file-like об'єкт.
UploadFile
UploadFile має такі атрибути:
filename: Рядокstrз оригінальною назвою файлу, який був завантажений (наприклад,myimage.jpg).content_type: Рядокstrз типом вмісту (MIME type / media type) (наприклад,image/jpeg).file:SpooledTemporaryFile(file-like об'єкт). Це фактичний файловий об'єкт Python, який ви можете передавати безпосередньо іншим функціям або бібліотекам, що очікують «file-like» об'єкт.
UploadFile має такі асинхронні async методи. Вони всі викликають відповідні методи файлу під капотом (використовуючи внутрішній SpooledTemporaryFile).
write(data): Записуєdata(strабоbytes) у файл.read(size): Читаєsize(int) байтів/символів з файлу.seek(offset): Переходить до байтової позиціїoffset(int) у файлі.- Наприклад,
await myfile.seek(0)перейде на початок файлу. - Це особливо корисно, якщо ви виконаєте
await myfile.read()один раз, а потім потрібно знову прочитати вміст.
- Наприклад,
close(): Закриває файл.
Оскільки всі ці методи є асинхронними async методами, вам потрібно їх «await»-ити.
Наприклад, всередині async функції операції шляху ви можете отримати вміст за допомогою:
contents = await myfile.read()
Якщо ви знаходитесь у звичайній def функції операції шляху, ви можете отримати доступ до UploadFile.file безпосередньо, наприклад:
contents = myfile.file.read()
/// note | Технічні деталі async
Коли ви використовуєте async методи, FastAPI виконує файлові методи у пулі потоків і очікує на них.
///
/// note | Технічні деталі Starlette
UploadFile у FastAPI успадковується безпосередньо від UploadFile у Starlette, але додає деякі необхідні частини, щоб зробити його сумісним із Pydantic та іншими частинами FastAPI.
///
Що таке «Form Data»
Спосіб, у який HTML-форми (<form></form>) надсилають дані на сервер, зазвичай використовує «спеціальне» кодування для цих даних, відмінне від JSON.
FastAPI забезпечить зчитування цих даних з правильного місця, а не з JSON.
/// note | Технічні деталі
Дані з форм зазвичай кодуються за допомогою «media type» application/x-www-form-urlencoded, якщо вони не містять файлів.
Але якщо форма містить файли, вона кодується як multipart/form-data. Якщо ви використовуєте File, FastAPI знатиме, що потрібно отримати файли з правильної частини тіла.
Якщо ви хочете дізнатися більше про ці типи кодування та формові поля, ознайомтеся з MDN web docs для POST.
///
/// warning | Попередження
Ви можете оголосити кілька параметрів File і Form в операції шляху, але ви не можете одночасно оголошувати поля Body, які ви очікуєте отримати як JSON, оскільки запит матиме тіло, закодоване як multipart/form-data, а не application/json.
Це не обмеження FastAPI, а частина протоколу HTTP.
///
Необов’язкове завантаження файлу
Ви можете зробити файл необов’язковим, використовуючи стандартні анотації типів і встановивши значення за замовчуванням None:
{* ../../docs_src/request_files/tutorial001_02_an_py310.py hl[9,17] *}
UploadFile із додатковими метаданими
Ви також можете використовувати File() разом із UploadFile, наприклад, щоб встановити додаткові метадані:
{* ../../docs_src/request_files/tutorial001_03_an_py39.py hl[9,15] *}
Завантаження кількох файлів
Можна завантажувати кілька файлів одночасно.
Вони будуть пов’язані з одним і тим самим «form field», який передається у вигляді «form data».
Щоб це реалізувати, потрібно оголосити список bytes або UploadFile:
{* ../../docs_src/request_files/tutorial002_an_py39.py hl[10,15] *}
Ви отримаєте, як і було оголошено, list із bytes або UploadFile.
/// note | Технічні деталі
Ви також можете використати from starlette.responses import HTMLResponse.
FastAPI надає ті ж самі starlette.responses, що й fastapi.responses, просто для зручності для вас, розробника. Але більшість доступних відповідей надходять безпосередньо від Starlette.
///
Завантаження кількох файлів із додатковими метаданими
Так само як і раніше, ви можете використовувати File(), щоб встановити додаткові параметри навіть для UploadFile:
{* ../../docs_src/request_files/tutorial003_an_py39.py hl[11,18:20] *}
Підсумок
Використовуйте File, bytes та UploadFile, щоб оголошувати файли для завантаження в запиті, надіслані у вигляді form data.