Файлы Telegram в Python: API и инструменты
Работа с файлами Telegram через Python
Telegram Bot API предоставляет возможности для обмена файлами: изображениями, документами, аудио и видео. Для работы с этими файлами в Python существует несколько библиотек, среди которых наиболее популярны python-telegram-bot (синхронный/асинхронный), aiogram (асинхронный) и Telethon (для пользовательских аккаунтов). Ниже рассмотрены основные подходы с примерами кода и разбором типичных проблем.
Как скачать файл из сообщения с помощью python-telegram-bot?
Библиотека python-telegram-bot предоставляет удобный интерфейс для работы с файлами. После получения объекта Message можно вызвать метод get_file() и затем download(). Пример:
from telegram import Bot
from telegram.ext import Updater, MessageHandler, Filters
def handle_file(update, context):
file = update.message.document.get_file()
file.download('downloaded_file.pdf')
update.message.reply_text('Файл сохранён')
updater = Updater(token='YOUR_TOKEN', use_context=True)
dp = updater.dispatcher
dp.add_handler(MessageHandler(Filters.document, handle_file))
updater.start_polling()
updater.idle()Telegram file python (работа с файлами telegram в python)
Пояснение: get_file() возвращает объект File с информацией о файле и ссылкой для скачивания. Метод download() сохраняет содержимое на диск. Для изображений используется update.message.photo[-1].get_file().
Типичные проблемы:
- Ошибка 400 Bad Request: file_id is invalid - файл устарел или удалён. Необходимо обрабатывать исключения.
- Превышение лимита размера файла (50 МБ для ботов). Для больших файлов требуется серверное скачивание через file_path и requests.
Как загрузить файл в чат через бота?
Для отправки файла используется метод send_document() (или send_photo, send_audio). Файл может быть передан как объект InputFile, путь или поток:
from telegram import Bot
bot = Bot(token='YOUR_TOKEN')
with open('report.xlsx', 'rb') as f:
bot.send_document(chat_id='@channel', document=f)Open api python (openapi (swagger) в python)
Если файл уже находится в облаке Telegram (есть file_id), можно отправить его повторно, передав file_id как строку. Это позволяет избежать повторной загрузки.
Проблемы: При отправке больших файлов (>20 МБ) может потребоваться разбиение на части. Ошибка 413 Request Entity Too Large - файл слишком велик для прямого POST запроса.
Как скачать файл в оперативную память, не сохраняя на диск?
Иногда требуется обработать файл без записи на диск. Для этого передают BytesIO или StringIO в download():
from io import BytesIO
file = update.message.document.get_file()
buffer = BytesIO()
file.download(out=buffer)
buffer.seek(0)
# теперь содержимое файла в буфере
content = buffer.read()проверка ключа python (проверка api ключа в python)
Этот подход удобен для обработки изображений (например, с помощью Pillow) или анализа текстовых файлов.
Внимание: При работе с большими файлами (>100 МБ) удержание всего содержимого в памяти может привести к исчерпанию памяти. В таких случаях лучше использовать потоковую запись.
Как обрабатывать медиа-группы (альбомы)?
Медиа-группы - это набор медиафайлов, отправленных одновременно. В python-telegram-bot используется MessageHandler с фильтром Filters.media_group. Пример:
def handle_media_group(update, context):
for photo in update.message.media_group:
file = photo[-1].get_file()
file.download()
updater.dispatcher.add_handler(MessageHandler(Filters.media_group, handle_media_group))Метод media_group возвращает список объектов Message. Важно обработать все файлы, так как каждый из них приходит отдельным апдейтом.
Ошибка: Иногда апдейты приходят не одновременно, и для корректного сбора всех элементов требуется хранить временный словарь по media_group_id.
Как работать с файлами в aiogram (асинхронно)?
Библиотека aiogram использует aiohttp и asyncio. Скачивание файла выглядит аналогично, но с await:
from aiogram import Bot, Dispatcher, types
from aiogram.contrib.middlewares.logging import LoggingMiddleware
bot = Bot(token='YOUR_TOKEN')
dp = Dispatcher(bot)
@dp.message_handler(content_types=['document'])
async def handle_document(message: types.Message):
file = await message.document.get_file()
await file.download('document.pdf')
await message.answer('Файл сохранён')
if __name__ == '__main__':
from aiogram import executor
executor.start_polling(dp)Преимущество - неблокирующий ввод-вывод, что полезно при большом количестве одновременных запросов.
Проблема: В aiogram версии 3.x изменилось API. В версии 2.x используется types.Message, в 3.x - types.Document. Следует уточнять документацию.
Как использовать Telethon для файлов из пользовательского аккаунта?
Telethon предназначен для работы с MTProto (пользователи Telegram). Скачивание файла:
from telethon import TelegramClient, events
client = TelegramClient('session', api_id, api_hash)
@client.on(events.NewMessage)
async def handler(event):
if event.message.file:
path = await event.message.download_media(file='downloads/')
print('Скачано в', path)
client.start()
client.run_until_disconnected()Подходит для скачивания файлов из своих чатов, каналов. Для ботов не используется.
Ошибка: Если не указать file, Telethon сохранит с оригинальным именем. При отсутствии прав на скачивание (например, в закрытом канале) возникает исключение.
Расширенные примеры работы с файлами Telegram
Потоковая загрузка большого файла через итерацию
Избежать занятия всей памяти можно, скачивая файл частями. В библиотеке python-telegram-bot метод download() по умолчанию загружает сразу всё. Для потоковой записи используем requests напрямую, получая ссылку через file.file_path:
import requests
from telegram import Bot
bot = Bot(token='YOUR_TOKEN')
file = bot.get_file('file_id')
url = file.file_path
response = requests.get(url, stream=True)
with open('large_file.bin', 'wb') as f:
for chunk in response.iter_content(chunk_size=8192):
f.write(chunk)# Результат: файл сохраняется на диск, не загружая весь в память
Этот метод подходит для файлов размером более 50 МБ (предел для бота - 50 МБ, но если файл уже загружен в облако, то file_path выдаёт прямую ссылку).
Скачивание и обработка изображения на лету
Пример с Pillow: получим фото, изменим размер и сохраним результат:
from io import BytesIO
from PIL import Image
from telegram import Bot
bot = Bot(token='YOUR_TOKEN')
file = bot.get_file('file_id')
buffer = BytesIO()
file.download(out=buffer)
buffer.seek(0)
img = Image.open(buffer)
img_resized = img.resize((200, 200))
img_resized.save('resized.jpg')# Результат: файл resized.jpg 200x200 создан на диске
Загрузка файла из URL напрямую в Telegram
Можно отправить файл, не сохраняя его локально, указав URL в send_document через параметр document (в aiogram передают InputFile.from_url):
from telegram import Bot, InputFile
bot = Bot(token='YOUR_TOKEN')
url = 'https://example.com/sample.pdf'
bot.send_document(chat_id='@channel', document=InputFile.from_url(url))# Бот скачивает файл с URL и отправляет в чат
Это удобно, когда файл уже есть в сети и не требуется промежуточное хранение.
Работа с файловыми потоками в aiogram
Асинхронный пример с использованием aiofiles для записи частями:
import aiofiles
from aiogram import Bot, types
bot = Bot(token='YOUR_TOKEN')
async def download_media(message: types.Message):
file = await message.document.get_file()
file_path = file.file_path
async with aiofiles.open('output.bin', 'wb') as f:
async for chunk in bot.stream_file(file_path):
await f.write(chunk)# Файл записывается асинхронно, не блокируя цикл событий
Метод stream_file возвращает асинхронный генератор. Требуется aiogram версии 3.x.
Скачивание файла с перехватом прогресса
Можно отслеживать прогресс загрузки, используя кастомный callback в requests:
import requests
from tqdm import tqdm
url = 'https://api.telegram.org/file/botTOKEN/file_path'
response = requests.get(url, stream=True)
total = int(response.headers.get('content-length', 0))
with open('bigfile.zip', 'wb') as f, tqdm(total=total, unit='B', unit_scale=True) as pbar:
for data in response.iter_content(chunk_size=1024):
f.write(data)
pbar.update(len(data))# Выводится прогресс-бар загрузки