Pregunta

Digamos que desea guardar un montón de archivos en algún lugar, por ejemplo en BLOB.Digamos que desea distribuir estos archivos a través de una página web y hacer que el cliente abra automáticamente la aplicación/visor correcto.

Suposición:El navegador determina qué aplicación/visor usar mediante el encabezado de tipo mime (¿tipo de contenido?) en la respuesta HTTP.

Según esa suposición, además de los bytes del archivo, también desea guardar el tipo MIME.

¿Cómo encontrarías el tipo MIME de un archivo?Actualmente estoy en una Mac, pero esto también debería funcionar en Windows.

¿El navegador agrega esta información al publicar el archivo en la página web?

¿Existe una biblioteca Python ordenada para encontrar esta información?¿Un WebService o (aún mejor) una base de datos descargable?

¿Fue útil?

Solución

El método python-magic sugerido por toivotuo está desactualizado. Magia de Python El tronco actual está en Github y, según el archivo Léame allí, encontrar el tipo MIME se hace así.

# For MIME types
>>> import magic
>>> mime = magic.Magic(mime=True)
>>> mime.from_file("testdata/test.pdf")
'application/pdf'
>>>

Otros consejos

El módulo de tipos mime en la biblioteca estándar determinará/adivinará el tipo MIME a partir de una extensión de archivo.

Si los usuarios cargan archivos, la publicación HTTP contendrá el tipo MIME del archivo junto con los datos.Por ejemplo, Django hace que estos datos estén disponibles como un atributo del Archivo subido objeto.

Una forma más confiable que usar la biblioteca mimetypes sería usar el paquete python-magic.

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

Esto sería equivalente a usar el archivo (1).

En Django también se puede asegurar que el tipo MIME coincida con el de UploadedFile.content_type.

Esto parece ser muy fácil.

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

Consulte Publicación antigua

Hay 3 bibliotecas diferentes que envuelven libmagic.

2 de ellos están disponibles en pypi (por lo que la instalación de pip funcionará):

  • archivomagia
  • magia-python

Y otro, similar a python-magic, está disponible directamente en las últimas fuentes de libmagic, y es el que probablemente tenga en su distribución de Linux.

En Debian, el paquete python-magic se trata de este y se usa como dijo toivotuo y no está obsoleto como dijo Simon Zimmermann (en mi humilde opinión).

Me parece otra toma (del autor original de libmagic).

Lástima que no esté disponible directamente en pypi.

en Python 2.6:

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

No indicaste qué servidor web estabas usando, pero Apache tiene un pequeño módulo llamado Magia de mimo que utiliza para determinar el tipo de archivo cuando se le indica que lo haga.Lee parte del contenido del archivo e intenta averiguar de qué tipo es en función de los caracteres encontrados.Y como Dave Webb mencionado el Módulo de tipos Mime en Python funcionará, siempre que haya una extensión a mano.

Alternativamente, si está sentado en una caja UNIX, puede usar sys.popen('file -i ' + fileName, mode='r') para tomar el tipo MIME.Windows debería tener un comando equivalente, pero no estoy seguro de cuál es.

El método de @toivotuo funcionó mejor y de manera más confiable para mí en python3.Mi objetivo era identificar archivos comprimidos con gzip que no tienen una extensión .gz confiable.Instalé 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))

para un archivo comprimido con gzip devuelve:aplicación/gzip;juego de caracteres=binario

para un archivo txt descomprimido (datos iostat):Texto sin formato;conjunto de caracteres = nosotros-ascii

para un archivo tar:aplicación/x-alquitrán;juego de caracteres=binario

para un archivo bz2:aplicación/x-bzip2;juego de caracteres=binario

y por último, pero no menos importante para mí, un archivo .zip:aplicación/zip;juego de caracteres=binario

En Python 3.x y aplicación web con URL al archivo que no puede tener una extensión o una extensión falsa.Deberías instalar python-magic, usando

pip3 install python-magic

Para Mac OS X, también debes instalar libmagic usando

brew install libmagic

Fragmento de código

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)

alternativamente puedes poner un tamaño en la lectura

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)

Actualización 2017

No es necesario ir a github, está en PyPi con un nombre diferente:

pip3 install --user python-magic
# or:
sudo apt install python3-magic  # Ubuntu distro package

El código también se puede simplificar:

>>> import magic

>>> magic.from_file('/tmp/img_3304.jpg', mime=True)
'image/jpeg'

Enlaces de Python a libmagic

Todas las diferentes respuestas sobre este tema son muy confusas, por lo que espero brindar un poco más de claridad con esta descripción general de las diferentes vinculaciones de libmagic.Anteriormente mamadori dio un respuesta corta enumerando la opción disponible.

libmagic

Al determinar el tipo mime de un archivo, la herramienta elegida simplemente se llama file y su back-end se llama libmagic.(Ver el Página de inicio del proyecto.) El proyecto se desarrolla en un repositorio cvs privado, pero hay un espejo git de solo lectura en github.

Ahora bien, esta herramienta, que necesitará si desea utilizar cualquiera de los enlaces de libmagic con Python, ya viene con sus propios enlaces de Python llamados file-magic.No hay mucha documentación dedicada a ellos, pero siempre puedes echar un vistazo a la página de manual de c-library: man libmagic.El uso básico se describe en el archivo Léame:

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)

Aparte de esto, también puedes utilizar la biblioteca creando un Magic objeto usando magic.open(flags) como se muestra en el archivo de ejemplo.

Ambos toivotuo y ewr2san usa estos file-magic fijaciones incluidas en el file herramienta.Asumen erróneamente que están usando el python-magic paquete. Esto parece indicar que si ambos file y python-magic están instalados, el módulo Python magic se refiere al anterior.

magia-python

Esta es la biblioteca de la que habla Simon Zimmermann en su respuesta y que también es empleado por Claude COULOMBE así como gringo suave.

archivomagia

Nota:¡Este proyecto se actualizó por última vez en 2013!

Debido a que está basada en la misma c-api, esta biblioteca tiene cierta similitud con file-magic incluido en libmagic.Sólo es mencionado por mamadori y ninguna otra respuesta lo emplea.

El módulo mimetypes simplemente reconoce un tipo de archivo según su extensión.Si intenta recuperar un tipo de archivo sin extensión, los tipos MIME no funcionarán.

He probado muchos ejemplos pero con Django. mutageno juega muy bien.

Ejemplo de comprobación de si los archivos están mp3

from mutagen.mp3 import MP3, HeaderNotFoundError  

try:
    audio = MP3(file)
except HeaderNotFoundError:
    raise ValidationError('This file should be mp3')

La desventaja es que su capacidad para verificar tipos de archivos es limitada, pero es una excelente manera si no solo desea verificar el tipo de archivo sino también acceder a información adicional.

Puede que esto ya sea antiguo, pero ¿por qué no utilizar UploadedFile.content_type directamente desde Django?¿No es lo mismo?(https://docs.djangoproject.com/en/1.11/ref/files/uploads/#django.core.files.uploadedfile.UploadedFile.content_type)

Para los datos de tipo de matriz de byte, puede usar magia.from_buffer (_byte_array, mime = true)

Primero pruebo la biblioteca de tipos MIME.Si no funciona, uso la biblioteca python-magic.

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

puedes usar imghdr Módulo de Python.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top