Как найти mime-тип файла в python?
Вопрос
Допустим, вы хотите сохранить где-нибудь кучу файлов, например, в виде больших двоичных объектов.Допустим, вы хотите отправить эти файлы через веб-страницу, и клиент автоматически откроет нужное приложение / средство просмотра.
Предположение:Браузер определяет, какое приложение / средство просмотра использовать, по типу mime (content-type?) заголовку в HTTP-ответе.
Исходя из этого предположения, в дополнение к байтам файла, вы также хотите сохранить тип MIME.
Как бы вы определили MIME-тип файла?В настоящее время я работаю на Mac, но это также должно работать и на Windows.
Добавляет ли браузер эту информацию при размещении файла на веб-странице?
Существует ли удобная библиотека python для поиска этой информации?Веб-сервис или (что еще лучше) загружаемая база данных?
Решение
Метод python-magic, предложенный toivotuo, устарел. Python-магия текущий транк находится на Github и, основываясь на тамошнем readme, поиск MIME-типа выполняется следующим образом.
# For MIME types
>>> import magic
>>> mime = magic.Magic(mime=True)
>>> mime.from_file("testdata/test.pdf")
'application/pdf'
>>>
Другие советы
Тот Самый модуль mimetypes ( миметипы ) в стандартной библиотеке будет определяться / угадываться тип MIME по расширению файла.
Если пользователи загружают файлы, HTTP-сообщение будет содержать MIME-тип файла наряду с данными.Например, Django делает эти данные доступными в качестве атрибута Загруженный файл объект.
Более надежным способом, чем использование библиотеки mimetypes, было бы использование пакета python-magic.
import magic
m = magic.open(magic.MAGIC_MIME)
m.load()
m.file("/tmp/document.pdf")
Это было бы эквивалентно использованию file(1).
В Django также можно было бы убедиться, что тип MIME совпадает с типом UploadedFile.content_type .
Это кажется очень простым
>>> from mimetypes import MimeTypes
>>> import urllib
>>> mime = MimeTypes()
>>> url = urllib.pathname2url('Upload.xml')
>>> mime_type = mime.guess_type(url)
>>> print mime_type
('application/xml', None)
Пожалуйста, обратитесь к Старый Пост
Существует 3 различные библиотеки, которые обертывают libmagic.
2 из них доступны на pypi (так что установка pip будет работать):
- filemagic ( файловая магия)
- питон-магия
И еще один, похожий на python-magic, доступен непосредственно в последних источниках libmagic, и он, вероятно, есть у вас в вашем дистрибутиве Linux.
В Debian пакет python-magic примерно такой, и он используется, как сказал тойвотуо, и он не устарел, как сказал Саймон Циммерманн (ИМХО).
Мне кажется, это другой подход (оригинального автора libmagic).
Жаль, что он недоступен непосредственно в pypi.
в python 2.6:
mime = subprocess.Popen("/usr/bin/file --mime PATH", shell=True, \
stdout=subprocess.PIPE).communicate()[0]
Вы не указали, какой веб-сервер вы используете, но в Apache есть симпатичный маленький модуль под названием Магия Пантомимы который он использует для определения типа файла, когда ему говорят это сделать.Он считывает часть содержимого файла и пытается определить, к какому типу он относится, основываясь на найденных символах.И как Дэйв Уэбб Упомянул тот самый Модуль MimeTypes ( миметипы ) под управлением python будет работать, при условии, что расширение будет удобным.
В качестве альтернативы, если вы сидите на ящике UNIX, вы можете использовать sys.popen('file -i ' + fileName, mode='r')
чтобы получить MIME-тип.В Windows должна быть эквивалентная команда, но я не уверен, что это такое.
Метод @toivotuo работал лучше всего и надежнее всего для меня под python3.Моей целью было идентифицировать архивированные файлы, которые не имеют надежного расширения .gz.Я установил python3-magic.
import magic
filename = "./datasets/test"
def file_mime_type(filename):
m = magic.open(magic.MAGIC_MIME)
m.load()
return(m.file(filename))
print(file_mime_type(filename))
для архивированного файла он возвращает:приложение /gzip;кодировка= двоичная
для распакованного текстового файла (данные iostat):текстовый /обычный;кодировка=us-ascii
для файла tar:применение/x-tar;кодировка= двоичная
для файла bz2:приложение/x-bzip2;кодировка= двоичная
и последнее, но не менее важное для меня - zip-файл:приложение/zip;кодировка= двоичная
В Python 3.x и webapp с URL-адресом к файлу, который не может иметь расширение или поддельное расширение.Вы должны установить python-magic, используя
pip3 install python-magic
Для Mac OS X вам также следует установить libmagic с помощью
brew install libmagic
Фрагмент кода
import urllib
import magic
from urllib.request import urlopen
url = "http://...url to the file ..."
request = urllib.request.Request(url)
response = urlopen(request)
mime_type = magic.from_buffer(response.readline())
print(mime_type)
в качестве альтернативы вы могли бы указать размер в поле для чтения
import urllib
import magic
from urllib.request import urlopen
url = "http://...url to the file ..."
request = urllib.request.Request(url)
response = urlopen(request)
mime_type = magic.from_buffer(response.read(128))
print(mime_type)
Обновление за 2017 год
Не нужно заходить на github, он есть на PyPI под другим именем:
pip3 install --user python-magic
# or:
sudo apt install python3-magic # Ubuntu distro package
Код также может быть упрощен:
>>> import magic
>>> magic.from_file('/tmp/img_3304.jpg', mime=True)
'image/jpeg'
Привязки Python к libmagic
Все различные ответы на эту тему очень запутанны, поэтому я надеюсь внести немного больше ясности в этот обзор различных привязок libmagic.Ранее мамедори дал краткий ответ перечисление доступных опций.
libmagic ( библиотека магии )
- имя модуля:
magic
- pypi: файл-волшебство
- Источник: https://github.com/file/file/tree/master/python
При определении mime-типа файлов выбранный инструмент просто вызывается file
и его серверная часть называется libmagic
.(Смотрите Домашняя страница проекта.) Проект разрабатывается в частном cvs-репозитории, но есть зеркало git, доступное только для чтения, на github.
Теперь этот инструмент, который вам понадобится, если вы захотите использовать любую из привязок libmagic с python, уже поставляется со своими собственными привязками python, называемыми file-magic
.Для них не так много специальной документации, но вы всегда можете заглянуть на справочную страницу c-библиотеки: man libmagic
.Основное использование описано в файл readme:
import magic
detected = magic.detect_from_filename('magic.py')
print 'Detected MIME type: {}'.format(detected.mime_type)
print 'Detected encoding: {}'.format(detected.encoding)
print 'Detected file type name: {}'.format(detected.name)
Помимо этого, вы также можете использовать библиотеку, создав Magic
объект, использующий magic.open(flags)
как показано на рисунке пример файла.
И то , и другое тойвотуо и ewr2san использует эти file-magic
привязки, включенные в file
инструмент.Они ошибочно предполагают, что используют python-magic
посылка. Это, по-видимому, указывает на то, что если оба file
и python-magic
установлены, модуль python magic
относится к первому варианту.
питон-магия
- имя модуля:
magic
- pypi: питон-магия
- Источник: https://github.com/ahupp/python-magic
Это библиотека , о которой рассказывает Саймон Циммерман в его ответ и который также используется Клод КУЛОМБ а также Учтивый Гринго.
filemagic ( файловая магия)
- имя модуля:
magic
- pypi: filemagic ( файловая магия)
- Источник: https://github.com/aliles/filemagic
Примечание:Последний раз этот проект обновлялся в 2013 году!
Благодаря тому, что эта библиотека основана на том же c-api, она имеет некоторое сходство с file-magic
включено в libmagic
.Это упоминается только маммадори и ни в каком другом ответе это не используется.
Модуль mimetypes просто распознает тип файла на основе расширения файла.Если вы попытаетесь восстановить тип файла без расширения, mimetypes не будет работать.
Я перепробовал множество примеров , но с Django мутаген играет хорошо.
Пример проверки наличия файлов mp3
from mutagen.mp3 import MP3, HeaderNotFoundError
try:
audio = MP3(file)
except HeaderNotFoundError:
raise ValidationError('This file should be mp3')
Недостатком является то, что ваши возможности проверять типы файлов ограничены, но это отличный способ, если вы хотите не только проверить тип файла, но и получить доступ к дополнительной информации.
Возможно, это уже устарело, но почему бы не использовать UploadedFile.content_type непосредственно из Django?Разве это не одно и то же?(https://docs.djangoproject.com/en/1.11/ref/files/uploads/#django.core .файлы.загруженный файл.Загруженный файл.content_type)
Для данных типа массива байт вы можете использовать magic.from_buffer(_byte_array,mime= True)
Сначала я пробую библиотеку mimetypes.Если это не работает, я использую вместо этого библиотеку python-magic libary.
import mimetypes
def guess_type(filename, buffer=None):
mimetype, encoding = mimetypes.guess_type(filename)
if mimetype is None:
try:
import magic
if buffer:
mimetype = magic.from_buffer(buffer, mime=True)
else:
mimetype = magic.from_file(filename, mime=True)
except ImportError:
pass
return mimetype
вы можете использовать imghdr Модуль Python.