Как отправить файл с помощью POST-запроса в Python

«Как отправить файл с помощью POST-запроса в Python» — вопрос из категории Сети, который задают на 10% собеседований Python Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Для отправки файлов используется POST-запрос с типом содержимого multipart/form-data. Этот формат позволяет передавать бинарные данные (файл) вместе с другими текстовыми полями в одном запросе.

В Python это легко реализовать с помощью библиотеки requests.

Синхронный пример (requests):

import requests

# URL-адрес сервера, который принимает файлы
url = 'https://httpbin.org/post'

# Файл открывается в бинарном режиме для чтения ('rb')
with open('my_file.txt', 'rb') as f:
    # Словарь `files` указывает имя поля ('file') и файловый объект
    files = {'file': f}
    response = requests.post(url, files=files)

print(f"Статус-код: {response.status_code}")
print(response.json())

Ключевые моменты:

  • Файл необходимо открывать в бинарном режиме ('rb').
  • Данные передаются в параметре files в виде словаря, где ключ — это имя поля формы, а значение — файловый объект.
  • Сервер на принимающей стороне должен быть настроен на обработку multipart/form-data.

Асинхронный пример (aiohttp):

Для асинхронных приложений используется схожий подход с aiohttp.FormData.

import aiohttp
import asyncio

async def upload_file():
    async with aiohttp.ClientSession() as session:
        data = aiohttp.FormData()
        # Добавляем поле с файлом
        data.add_field('file',
                       open('my_file.txt', 'rb'),
                       filename='my_file.txt',
                       content_type='text/plain')

        async with session.post('https://httpbin.org/post', data=data) as resp:
            print(f"Статус-код: {resp.status}")
            print(await resp.json())

asyncio.run(upload_file())