Как найти тип mime файла в python?


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

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

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

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

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

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

16 145

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'
>>>

The модуль mimetypes в стандартной библиотеке определит / угадает тип MIME из расширения файла.

Если пользователи загружают файлы, HTTP post будет содержать тип 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 имеет приятный маленький модуль под названием MIME Magic который он использует для определения типа файла, когда ему говорят об этом. Он читает часть содержимого файла и пытается выяснить, какой тип он основан на найденных символах. И как Дэйв Уэбб Упомянул the Модуль MimeTypes под python будет работать, при условии, что расширение удобно.

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

@toivotuo 's метод работал лучше и надежнее всего для меня под 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))

для архивированного файла она возвращает: 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)

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

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. Для них не так много специальной документации, но вы всегда можете посмотреть на man-страницу c-library: man libmagic. Основное использование описано в readme file:

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.