# python-magic: самый практичный способ доверять содержимому файла, а не расширению Когда на сервере появляется функция загрузки изображений, рано или поздно возникают такие требования. * «Файл пришёл как `.png`, но действительно ли это PNG?» * «Нужно сначала определить, является ли файл изображением или документом.» * «Перед тем как вызвать внешние парсеры (Pillow/OpenCV), хотелось бы хотя бы проверить тип.» В этом случае самым надёжным отправным пунктом является **содержимое файла**, а не его расширение. И самый простой способ получить «проверку по содержимому» — это `python-magic`. --- ## Что делает python-magic {#sec-2dbc8c320d7d} `python-magic` — это обёртка над C-библиотекой **libmagic**. libmagic анализирует **заголовок** (первые несколько байт) файла и определяет его тип. Та же функциональность доступна в Unix-команде `file`. Итак: * `file` (команда Linux) = «интерфейс в терминале» * `libmagic` = «ядро (логика определения)» * `python-magic` = «тонкая обёртка, позволяющая вызывать libmagic из Python» В этой статье мы сосредоточимся на `python-magic` и разберём, как именно этот движок определяет тип файла. --- ## Как работает ядро libmagic {#sec-275071254ba5} ![Диаграмма работы библиотеки libmagic](/media/editor_temp/6/0d5baf67-d72a-4f8d-9f1b-e273eaaba587.png) Суть libmagic проста: > «Читает базу правил определения типа файла, проверяет байты файла согласно этим правилам и выводит наиболее вероятный результат.» База правил — это **magic database** (magic pattern DB), которая обычно поставляется в скомпилированном виде (`magic.mgc`). ### 1) «Magic file» — набор правил {#sec-ddb47d204541} Правила состоят из: * **Где смотреть** (offset — позиция в файле) * **Как читать** (type — байт/строка/целое и т.д.) * **С чем сравнивать** (expected value/pattern) * **Какой вывод** (message/MIME и т.п.) Каждое правило проверяется строка за строкой, и при совпадении переходит к более конкретным подправилам, образуя иерархию. Для более подробного изучения команды `file` можно перейти по ссылке: [Изучаем команду file в Linux](https://cmdbox.mikihands.com/file/) ### 2) База правил — текст и скомпилированный формат {#sec-348444de0b9b} Magic DB может быть как читаемым текстом, так и скомпилированным бинарным файлом (`.mgc`) для повышения производительности. ### 3) Итог: проверка содержимого вместо расширения {#sec-cd8fcb1c198f} `file` всегда использует содержимое, а не расширение, чтобы определить тип. `python-magic` просто переносит эту философию в одну строку Python-кода. --- ## Как использовать python-magic {#sec-ec1c90199080} Существует два основных паттерна использования. ### 1) Получить MIME-тип (самый практичный) {#sec-8f4900070a82} Полезно при обработке загрузок, маршрутизации, логировании и метриках. ```python import magic mime = magic.from_file("upload.bin", mime=True) print(mime) # например: image/png ``` `python-magic` использует libmagic для определения типа файла, как и команда `file`. ### 2) Проверка по буферу (удобно для потоков загрузки) {#sec-e7a78ae5d55c} Перед сохранением на диск часто хочется быстро проверить первые байты. ```python import magic with open("upload.bin", "rb") as f: head = f.read(4096) mime = magic.from_buffer(head, mime=True) print(mime) ``` Буферная проверка особенно полезна как «первый фильтр» до сохранения файла. --- ## Где это полезно с точки зрения разработчика {#sec-03f012d163ca} ### 1) Первая линия защиты при проверке загрузок {#sec-a6c15b5bd9d3} * Не полагаться только на расширение * Минимально проверить, можно ли обрабатывать файл как изображение ### 2) Точки ветвления в пайплайне обработки {#sec-2122513f97f2} * Если изображение — перейти к ресайзу/миниатюрам * Если PDF/ZIP — отправить в другую очередь * Если тип неизвестен — изолировать/отклонить/дополнительно проверить ### 3) Сокращение затрат до вызова «тяжёлых декодеров» {#sec-92f50ef6ec8a} Pillow и подобные декодеры мощны, но их вызов увеличивает потребление памяти, CPU и поверхность уязвимостей. `python-magic` позволяет заранее решить, стоит ли вызывать декодер. > Важный практический момент: libmagic — это только **предположение/идентификация**. Для полной безопасности (запрет вредоносных нагрузок) нужны дополнительные проверки (белый список, ограничение размера, sandbox-декодинг и т.д.). --- ## Итог: python-magic — самый лёгкий способ получить определение типа файла в коде {#sec-397439f76216} `python-magic` не занимается обработкой изображений, а лишь быстро сообщает, как файл следует трактовать. * Движок — libmagic, как в `file` * Метод — «правила + проверка байтов» * Практика — проверка загрузок, маршрутизация, экономия ресурсов Освоив его, вы сможете в любой среде, где недоступны полноценные библиотеки, построить цепочку «определение → ветвление → защита». --- ## Предвкушение следующей статьи {#sec-b67a6eb8f216} * Что гарантируют методы `open()`, `load()`, `verify()` в Pillow (PIL) и когда их использовать? Мы разберём их работу и назначение. --- **Смотрите также** * [Как выглядит файл изображения с точки зрения разработчика? Разбираем структуру](/whitedec/2026/1/14/developer-view-image-file-common-structure/)