Отправка файлов через requests: методы и примеры
Отправка файла через библиотеку requests
Наиболее эффективный способ передачи файла с помощью библиотеки requests заключается в использовании параметра files в методе post(). Этот способ позволяет корректно сформировать multipart/form-data запрос, автоматически вычисляет заголовок Content-Type и размер файла. Пример:
import requests
url = 'https://httpbin.org/post'
with open('example.txt', 'rb') as f:
response = requests.post(url, files={'file': f})
print(response.status_code)
print(response.json())запрос страницы python (запрос веб-страницы в python)
Здесь файл открывается в бинарном режиме, передается в словаре с ключом 'file'. Сервер получает файл с именем 'example.txt'. После завершения запроса контекстный менеджер закрывает файл.
Типичные ошибки:
- Забыть открыть файл в режиме 'rb' - при текстовом режиме ('r') возможны проблемы с кодировкой.
- Не указывать имя файла - сервер может не принять данные.
- Использовать глобальный конструктор open без контекстного менеджера - риск утечки файлового дескриптора.
Как отправить файл с произвольным именем?
Если требуется изменить имя, передаваемое на сервер, можно использовать кортеж (filename, fileobj, content_type):
files = {'file': ('custom_name.txt', open('example.txt', 'rb'), 'text/plain')}
response = requests.post(url, files=files)Python requests (библиотека requests в python)
Первый элемент кортежа - новое имя, второй - файлоподобный объект, третий - MIME-тип (опционально).
Без указания MIME-типа requests попытается угадать его по расширению. При нестандартных расширениях лучше задавать явно.
Как отправить несколько файлов за один запрос?
В словаре files можно указать несколько ключей или один ключ со списком кортежей:
files = [
('file1', ('a.txt', open('a.txt', 'rb'), 'text/plain')),
('file2', ('b.txt', open('b.txt', 'rb'), 'text/plain'))
]
response = requests.post(url, files=files)
Http error requests python (обработка http ошибок в requests)
Это удобно для загрузки галереи изображений или пакета документов.
Как передать файл вместе с дополнительными полями формы?
Параметр data объединяется с files в одном POST запросе:
response = requests.post(url, data={'user': 'alice'}, files={'image': open('photo.jpg', 'rb')})Make request python (выполнение http-запроса)
Сервер получает и обычные поля, и файл.
Как отправить файл без сохранения на диске (из потока)?
Можно передать объект BytesIO:
from io import BytesIO
buffer = BytesIO(b'Some binary content')
response = requests.post(url, files={'file': ('data.bin', buffer, 'application/octet-stream')})Python urllib3 request (использование urllib3 для запросов)
Имя обязательно, иначе сервер может не распознать вложение.
Проблема: если не указать имя, requests может использовать имя 'unknown' или вовсе не отправить заголовок Content-Disposition, что нарушит стандарт.
Как отправить большой файл частями (chunked transfer encoding)?
Для отправки большого файла без загрузки в память целиком используется параметр data как генератор:
def generate_chunks(file_path, chunk_size=8192):
with open(file_path, 'rb') as f:
while chunk := f.read(chunk_size):
yield chunk
response = requests.post(url, data=generate_chunks('large_file.iso'), headers={'Transfer-Encoding': 'chunked'})Этот способ не использует files, а передаёт тело запроса напрямую. Подходит для потоковой передачи, но сервер должен поддерживать chunked encoding.
При таком подходе теряется информация об имени файла. Если сервер ожидает multipart/form-data, данный вариант не сработает.
Примеры с расширенными подробностями
Пример 1. Отправка файла с указанием MIME-типа
import requests
url = 'https://httpbin.org/post'
files = {'document': ('report.pdf', open('report.pdf', 'rb'), 'application/pdf')}
response = requests.post(url, files=files)
print('Status:', response.status_code)
print('Response:', response.json())Status: 200
Response: {'files': {'document': '... binary content ...'}, 'form': {}, ...}В ответе httpbin.org возвращает переданные файлы в поле 'files'.
Пример 2. Отправка нескольких файлов разных типов
url = 'https://httpbin.org/post'
with open('image.png', 'rb') as img, open('data.csv', 'rb') as csv:
files = [
('image', ('photo.png', img, 'image/png')),
('data', ('stats.csv', csv, 'text/csv'))
]
response = requests.post(url, files=files)
print('Files count:', len(response.json()['files']))Files count: 2
Каждый файл передан под своим ключом ('image', 'data').
Пример 3. Отправка файла из строки (BytesIO)
from io import BytesIO
import json
data = json.dumps({'key': 'value'}).encode()
bio = BytesIO(data)
files = {'upload': ('metadata.json', bio, 'application/json')}
response = requests.post('https://httpbin.org/post', files=files)
print('Uploaded file size:', len(response.json()['files']['upload']))Uploaded file size: 16
Полезно, если данные формируются динамически в памяти.
Пример 4. Отправка файла с сессией (автоматическое сохранение cookies)
session = requests.Session()
# предположим, что нужно авторизоваться
session.post('https://example.com/login', data={'user': 'admin', 'pass': 'secret'})
# затем загрузить файл
with open('new_data.txt', 'rb') as f:
response = session.post('https://example.com/upload', files={'file': f})
print(response.status_code)Сессия сохраняет куки, что позволяет передавать файлы на защищённые ресурсы.
Пример 5. Обработка ошибок при отправке
import requests
from requests.exceptions import RequestException
try:
with open('missing.txt', 'rb') as f:
resp = requests.post('http://httpbin.org/post', files={'file': f}, timeout=5)
resp.raise_for_status()
except FileNotFoundError:
print('Файл не найден')
except RequestException as e:
print('Ошибка запроса:', e)Код демонстрирует перехват исключений, связанных с отсутствием файла и сетевыми проблемами.