Работа с файлами⚓︎
TrueConf Chatbot Connector не накладывает ограничений на загрузку файлов на сервер. Однако, начиная с версии TrueConf Server 5.5.2 и выше, администратор может настроить ограничения на максимальный размер файла и допустимые форматы (расширения).
Библиотека python-trueconf-bot предоставляет удобные средства для работы с файлами: как для отправки, так и для загрузки. Чтобы отправить файл, используйте один из подклассов InputFile, в зависимости от источника данных.
Доступны три встроенных класса для передачи файлов:
- FSInputFile — загрузка файла с локальной файловой системы
- BufferedInputFile — загрузка из байтового буфера
- URLInputFile — загрузка файла с удалённого URL
Все классы расположены в модуле trueconf.types.
Вы можете использовать эти классы в методах:
- bot.send_document(...)
- bot.send_photo(...)
- bot.send_sticker(...)
Как отправить файл?⚓︎
🗂️ FSInputFile⚓︎
Используется для загрузки файлов с локальной файловой системы. Рекомендуется использовать, когда у вас есть путь к файлу.
from trueconf.types import FSInputFile
await bot.send_document(
chat_id="a1b2c3d4",
file=FSInputFile("docs/report.pdf"),
caption="📄 Annual report for **2025**",
parse_mode=ParseMode.MARKDOWN,
)
await bot.send_sticker(chat_id="a1b2c3d4", file=FSInputFile("stickers/cat.webp"))
🧠 BufferedInputFile⚓︎
Используется, когда файл уже находится в памяти (например, получен из API, загружен в память (ОЗУ) или из базы данных).
from trueconf.types import BufferedInputFile
image_bytes = open("image.jpg", "rb").read()
preview_bytes = open("preview.jpg", "rb").read()
await bot.send_photo(
chat_id="a1b2c3d4",
file=BufferedInputFile(file=image_bytes, filename="image.jpg"),
preview=BufferedInputFile(file=preview_bytes, filename="preview.jpg"),
caption="This is my photo",
)
Также доступен удобный метод from_file():
🌐 URLInputFile⚓︎
Если файл находится в интернете, вы можете указать ссылку и бот скачает его самостоятельно.
from trueconf.types import URLInputFile
file = URLInputFile(
url="https://example.com/image.png",
filename="image.png", # можно опустить — будет определено автоматически
)
Как определяется размер. Метод await file.prepare() читает только HTTP-заголовки (тип, имя, Content-Length) и не скачивает тело — это дёшево. Для динамических источников (например, камера отдаёт новый снимок на каждый запрос) Content-Length является лишь оценкой: точный размер становится известен после скачивания, и именно он передаётся серверу, поэтому размер всегда совпадает с отправленным содержимым.
- Один объект
URLInputFile= одно содержимое: повторные отправки иclone()используют уже скачанные байты и не качают файл заново. Нужен свежий кадр — создайте новый объект. await file.read(max_size=...)обрывает загрузку, если содержимое превысило лимит (при отправке лимитbot.max_file_sizeприменяется автоматически).
Рекомендации⚓︎
- MIME-тип: определяется автоматически. Если установлен пакет python-magic, MIME-тип будет вычислен по содержимому файла (байтам), что значительно точнее, чем определение по расширению. Установите его с зависимостями так:
- clone(): каждый тип файла поддерживает метод
.clone()— он создаёт новую копию объекта с другимid(object).
Как скачать файл?⚓︎
Для удобной загрузки входящих медиафайлов, таких как изображения (message.photo) или документы (message.document), библиотека предоставляет шорткат-метод .download(). Это синтаксический сахар над методом bot.download_file_by_id(...), упрощающий работу с вложениями.
Рекомендуется использовать именно .download(), так как он:
- автоматически получает file_id из объекта;
- использует текущий экземпляр бота;
- минимизирует количество кода.
@router.message(F.document)
async def handle_doc(msg: Message):
await msg.document.download(file_path="document.pdf")
Notes
Путь file_path может быть как относительным, так и абсолютным. Родительские каталоги создаются автоматически.
Также доступен метод download_file_by_id(...), если требуется более гибкий контроль:
Устаревший параметр dest_path трактуется как каталог, к которому добавляется имя файла с сервера. Для точного пути используйте file_path.
Определение MIME-типа с помощью python-magic⚓︎
MIME‑тип файла может определяться автоматически. В библиотеке поддерживаются два подхода:
- По расширению файла — работает без дополнительных зависимостей, но может быть неточным.
- По содержимому файла (bytes) — заметно точнее, но требует
python-magic.
Как это работает⚓︎
Пакет python-magic сам по себе MIME‑типы не определяет. Это Python‑обёртка над нативной (C‑шной) библиотекой libmagic, которая и выполняет распознавание типа файла по содержимому.
Именно поэтому python-magic может не работать «из коробки» на некоторых системах: Python‑пакет устанавливается через pip, но системная библиотека libmagic должна быть установлена отдельно.
Если libmagic отсутствует, импорт magic может завершиться ошибкой вида:
ImportError: failed to find libmagic. Check your installation
Установка⚓︎
Установите системные зависимости:
- macOS (Homebrew):
- Linux (Debian/Ubuntu):
- Windows:
Также рекомендуем ознакомиться с репозиторием https://github.com/ahupp/python-magic.
Примечания⚓︎
- При наличии
python-magicMIME‑тип определяется по байтам файла, что обычно точнее, чем определение по имени или расширению.