Как найти тип MIME файла в Python?

предположим, вы хотите сохранить кучу файлов где-нибудь, например, в BLOBs. Предположим, вы хотите отправить эти файлы через веб-страницу и автоматически открыть правильное приложение/средство просмотра.

предположение: браузер выясняет, какое приложение / средство просмотра использовать по типу mime (content-type?) заголовок в ответе HTTP.

основываясь на этом предположении, в дополнение к байтам файла вы также хотите сохранить MIME тип.

Как бы вы нашли тип MIME файла? В настоящее время я на Mac, но это также должно работать на Windows.

добавляет ли браузер эту информацию при публикации файла на веб-странице?

есть ли аккуратная библиотека python для поиска этой информации? Веб-сервис или (еще лучше) загружаемая база данных?

16 ответов


метод 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 делает эти данные доступными в качестве атрибута UploadedFile


более надежным способом, чем использовать библиотеку mimetypes, было бы использование пакета python-magic.

import magic
m = magic.open(magic.MAGIC_MIME)
m.load()
m.file("/tmp/document.pdf")

Это будет эквивалентно использованию файлов(1).

на Django можно также убедиться, что тип MIME соответствует типу UploadedFile.тип содержимого.


Это, кажется, очень легко

>>> 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 install будет работать):

  • filemagic
  • python-magic

и еще один, похожий на python-magic, доступен непосредственно в последних источниках libmagic, и это тот, который вы, вероятно, имеете в своем дистрибутиве linux.

в Debian пакет python-magic об этом, и он используется, как сказал toivotuo, и это не устарел, как сказал Симон Циммерман (ИМХО).

Мне кажется, еще один дубль (оригинальным автором libmagic).

слишком плохо не доступен непосредственно на pypi.


в python 2.6:

mime = subprocess.Popen("/usr/bin/file --mime PATH", shell=True, \
    stdout=subprocess.PIPE).communicate()[0]

вы не указали, какой веб-сервер вы используете, но у Apache есть хороший маленький модуль под названием Мим Магии, который он использует для определения типа файла, когда сказано, чтобы сделать так. Он читает часть содержимого файла и пытается выяснить, какой тип он основан на найденных символах. И как Дэйв Уэбб Упомянул на Модуль MimeTypes под python будет работать, если расширение удобно.

кроме того, если вы сидите на Unix box вы можете использовать sys.popen('file -i ' + fileName, mode='r') чтобы захватить тип MIME. Windows должна иметь эквивалентную команду, но я не уверен, что это такое.


метод@toivotuo работал лучше и надежнее всего для меня под python3. Моей целью было идентифицировать gzipped файлы, которые не имеют надежного .расширение 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))

для файла gzipped он возвращает: application / gzip; charset=binary

для распакованного txt-файла (данные iostat): text / plain; charset=us-ascii

для файла tar: application/x-tar; charset=binary

для файла bz2: применение/x-bzip2; кодировка=бинарные

и последнее, но не менее важное для меня .сжатый файл: application / zip; charset=binary


В 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)

в качестве альтернативы вы можете поместить размер в read

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)

модуль mimetypes просто распознает тип файла на основе расширения файла. Если вы попытаетесь восстановить тип файла файла без расширения, типы mimetypes не будут работать.


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

при определении типа 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) как показано в файл.

как toivotuo и ewr2san использовать эти file-magic привязки включены в . Они ошибочно предполагают, что они используют python-magic пакета. это, кажется, указывает на то, что если оба file и python-magic установлены, модуль python magic относится к бывшим.

python-magic

это библиотека, о которой Саймон Циммерман говорит в ответ и который также работает в Клод Куломб а также Гринго Учтивый.

filemagic

Примечание: последний раз этот проект обновлялся в 2013 году!

из-за того, что эта библиотека основана на том же C-api, эта библиотека имеет некоторое сходство с file-magic входит в libmagic. Это только упоминается mammadori и никакой другой ответ не использует его.


Я пробовал много примеров, но с 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? Не same?(https://docs.djangoproject.com/en/1.11/ref/files/uploads/#django.core.files.uploadedfile.UploadedFile.content_type)


для данных типа массива байтов вы можете использовать магия.from_buffer (_byte_array,mime=True)


можно использовать imghdr модуль Python.