Отправка файлов в Python: примеры и инструкции
Отправка файлов в Python: обзор методов
Передача файлов является распространенной задачей при разработке программного обеспечения. Python предоставляет множество библиотек для отправки данных как по сети, так и в пределах локальной файловой системы. Рассмотрим наиболее эффективные и альтернативные подходы.
Как отправить файл через HTTP запрос?
Библиотека requests позволяет загружать файлы на сервер методом POST. Это универсальный способ передачи данных через веб.
import requests
url = 'https://example.com/upload'
files = {'file': open('document.pdf', 'rb')}
response = requests.post(url, files=files)
print(response.status_code)Python run exe file (запуск exe-файла из python)
Пояснения: открываем файл в бинарном режиме, передаём в словарь files, отправляем запрос. Сервер принимает multipart/form-data.
Как отправить файл на FTP сервер?
Модуль ftplib встроен в Python.
from ftplib import FTP
ftp = FTP('ftp.example.com')
ftp.login(user='user', passwd='password')
with open('file.txt', 'rb') as f:
ftp.storbinary('STOR file.txt', f)
ftp.quit()Python send files (отправка файлов в python)
Пояснения: устанавливаем соединение, логинимся, отправляем файл командой STOR.
Как безопасно передать файл по SFTP?
Библиотека paramiko предоставляет SFTP-клиент.
import paramiko
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('hostname', username='user', password='pass')
sftp = ssh.open_sftp()
sftp.put('local_file.txt', 'remote_file.txt')
sftp.close()
ssh.close()
Python system path (системные вызовы и файловая система в python)
Пояснения: устанавливаем SSH-соединение, открываем SFTP-сессию, загружаем файл.
Как отправить файл как вложение к письму?
Используем модули smtplib и email.mime.
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders
msg = MIMEMultipart()
msg['From'] = 'from@example.com'
msg['To'] = 'to@example.com'
msg['Subject'] = 'Файл'
with open('file.txt', 'rb') as attachment:
part = MIMEBase('application', 'octet-stream')
part.set_payload(attachment.read())
encoders.encode_base64(part)
part.add_header('Content-Disposition', 'attachment; filename="file.txt"')
msg.attach(part)
with smtplib.SMTP('smtp.example.com', 587) as server:
server.starttls()
server.login('user', 'password')
server.send_message(msg)Python py file system (работа с файловой системой в python (os, shutil))
Пояснения: создаем multipart сообщение, вкладываем файл в кодировке base64, отправляем через SMTP.
Как скопировать файл в другую папку на локальном диске?
Модуль shutil предоставляет функцию copy2 для копирования с метаданными.
import shutil
shutil.copy2('source.txt', 'destination.txt')аргументы программы python (аргументы командной строки программы на python)
Пояснения: копирует содержимое и метаданные (время создания и пр.). Альтернатива: shutil.copy() - без метаданных.
Как отправить файл через сокет напрямую?
Используем модуль socket для передачи данных между процессами.
import socket
s = socket.socket()
s.connect(('localhost', 12345))
with open('file.txt', 'rb') as f:
data = f.read()
s.sendall(data)
s.close()Python вызов программы (вызов программы из python)
Пояснения: открываем сокет, отправляем всё содержимое. На стороне сервера необходимо принимать данные и записывать в файл.
Как отправить файл с помощью внешней команды scp?
Модуль subprocess позволяет вызывать системные утилиты.
import subprocess
subprocess.run(['scp', 'local_file.txt', 'user@host:/remote/path'])
Пояснения: scp копирует файл по SSH. Необходимо настроить SSH-ключи для автоматизации.
Расширенные примеры отправки файлов
Отправка файла с индикатором прогресса (HTTP)
Используется библиотека tqdm для отображения прогресса при загрузке больших файлов.
import requests
from tqdm import tqdm
url = 'https://example.com/upload'
file_path = 'large_file.zip'
with open(file_path, 'rb') as f:
total_size = os.path.getsize(file_path)
with tqdm(total=total_size, unit='B', unit_scale=True) as pbar:
class ProgressFile:
def __init__(self, file, pbar):
self.file = file
self.pbar = pbar
def read(self, size):
data = self.file.read(size)
self.pbar.update(len(data))
return data
progress_file = ProgressFile(f, pbar)
files = {'file': (file_path, progress_file)}
response = requests.post(url, files=files)
pbar.close()
print(response.status_code)
Вывод: 100%|██████████| 104857600/104857600 [00:10<00:00, 9.99MB/s] 200
Отправка архива (tar.gz) на FTP
Создание сжатого архива и отправка его на FTP-сервер.
import tarfile
import io
from ftplib import FTP
# Создаём архив в памяти
buffer = io.BytesIO()
with tarfile.open(fileobj=buffer, mode='w:gz') as tar:
tar.add('file1.txt')
tar.add('file2.txt')
buffer.seek(0)
ftp = FTP('ftp.example.com')
ftp.login('user', 'pass')
ftp.storbinary('STOR archive.tar.gz', buffer)
ftp.quit()
(без вывода, если успешно)
Параллельная отправка нескольких файлов через HTTP
Используется threading для параллельной загрузки.
import threading
import requests
def upload_file(url, file_path):
with open(file_path, 'rb') as f:
files = {'file': f}
response = requests.post(url, files=files)
print(f'{file_path}: {response.status_code}')
url = 'https://example.com/upload'
files = ['img1.png', 'img2.png', 'img3.png']
threads = []
for f in files:
t = threading.Thread(target=upload_file, args=(url, f))
t.start()
threads.append(t)
for t in threads:
t.join()
img1.png: 200 img2.png: 200 img3.png: 200
Эффективная отправка по сокету с помощью os.sendfile (Linux)
Функция sendfile позволяет передавать файл из дескриптора в сокет без копирования в userspace.
import os
import socket
s = socket.socket()
s.connect(('localhost', 12345))
with open('bigfile.bin', 'rb') as f:
fd = f.fileno()
size = os.fstat(fd).st_size
offset = 0
while offset < size:
sent = os.sendfile(s.fileno(), fd, offset, size - offset)
offset += sent
s.close()
(без вывода, файл передан)
Отправка файла по частям (chunked) в HTTP с записью прогресса
Для очень больших файлов используется стриминг через генератор.
import requests
def file_chunks(file_path, chunk_size=8192):
with open(file_path, 'rb') as f:
while True:
chunk = f.read(chunk_size)
if not chunk:
break
yield chunk
url = 'https://example.com/upload'
response = requests.post(url, data=file_chunks('huge_file.iso'))
print(response.status_code)
200