Comment trouver le type MIME d’un fichier en python ?
Question
Supposons que vous souhaitiez enregistrer un certain nombre de fichiers quelque part, par exemple dans des BLOB.Supposons que vous souhaitiez diffuser ces fichiers via une page Web et que le client ouvre automatiquement la bonne application/visionneuse.
Hypothèse:Le navigateur détermine quelle application/visionneuse utiliser grâce à l'en-tête mime-type (content-type ?) dans la réponse HTTP.
Sur la base de cette hypothèse, en plus des octets du fichier, vous souhaitez également enregistrer le type MIME.
Comment trouver le type MIME d’un fichier ?Je suis actuellement sur Mac, mais cela devrait également fonctionner sous Windows.
Le navigateur ajoute-t-il ces informations lors de la publication du fichier sur la page Web ?
Existe-t-il une bibliothèque Python intéressante pour trouver ces informations ?Un WebService ou (encore mieux) une base de données téléchargeable ?
La solution
La méthode python-magique suggérée par toivotuo est obsolète. Python-magie Le tronc actuel se trouve sur Github et, sur la base du fichier Lisez-moi, la recherche du type MIME se fait comme ceci.
# For MIME types
>>> import magic
>>> mime = magic.Magic(mime=True)
>>> mime.from_file("testdata/test.pdf")
'application/pdf'
>>>
Autres conseils
Le module de types MIME dans la bibliothèque standard déterminera/devinera le type MIME à partir d’une extension de fichier.
Si les utilisateurs téléchargent des fichiers, la publication HTTP contiendra le type MIME du fichier à côté des données.Par exemple, Django rend ces données disponibles en tant qu'attribut du Fichier téléchargé objet.
Un moyen plus fiable que d'utiliser la bibliothèque mimetypes serait d'utiliser le package python-magic.
import magic
m = magic.open(magic.MAGIC_MIME)
m.load()
m.file("/tmp/document.pdf")
Cela équivaudrait à utiliser file(1).
Sur Django, on peut également s'assurer que le type MIME correspond à celui de UploadedFile.content_type.
Cela semble être très facile
>>> 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)
Se il vous plaît se référer Ancien message
Il existe 3 bibliothèques différentes qui enveloppent libmagic.
2 d'entre eux sont disponibles sur pypi (donc pip install fonctionnera) :
- fichiermagique
- python-magie
Et un autre, similaire à python-magic, est disponible directement dans les dernières sources de libmagic, et c'est celui que vous avez probablement dans votre distribution Linux.
Dans Debian, le paquet python-magic concerne celui-ci et il est utilisé comme le dit toivotuo et il n'est pas obsolète comme l'a dit Simon Zimmermann (à mon humble avis).
Il me semble qu'il s'agit d'une autre version (de l'auteur original de libmagic).
Dommage qu'il ne soit pas disponible directement sur pypi.
en python 2.6 :
mime = subprocess.Popen("/usr/bin/file --mime PATH", shell=True, \
stdout=subprocess.PIPE).communicate()[0]
Vous n'avez pas indiqué quel serveur Web vous utilisiez, mais Apache a un joli petit module appelé Mime magique qu'il utilise pour déterminer le type d'un fichier lorsqu'on lui demande de le faire.Il lit une partie du contenu du fichier et essaie de déterminer de quel type il s'agit en fonction des caractères trouvés.Et comme Dave Webb mentionné le Module Types MIME sous python fonctionnera, à condition qu'une extension soit pratique.
Alternativement, si vous utilisez une machine UNIX, vous pouvez utiliser sys.popen('file -i ' + fileName, mode='r')
pour récupérer le type MIME.Windows devrait avoir une commande équivalente, mais je ne suis pas sûr de savoir de quoi il s'agit.
La méthode de @toivotuo a fonctionné de la manière la plus efficace et la plus fiable pour moi sous python3.Mon objectif était d'identifier les fichiers gzippés qui n'ont pas d'extension .gz fiable.J'ai installé 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))
pour un fichier gzippé, il renvoie :application/gzip ;jeu de caractères = binaire
pour un fichier txt décompressé (données iostat) :texte simple;charset=us-ascii
pour un fichier tar :application/x-tar ;jeu de caractères = binaire
pour un fichier bz2 :application/x-bzip2 ;jeu de caractères = binaire
et enfin et surtout pour moi un fichier .zip :application/zip ;jeu de caractères = binaire
Dans Python 3.x et webapp avec l'URL du fichier qui ne peut pas avoir d'extension ou une fausse extension.Vous devez installer python-magic, en utilisant
pip3 install python-magic
Pour Mac OS X, vous devez également installer libmagic en utilisant
brew install libmagic
Extrait de code
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)
alternativement, vous pouvez mettre une taille dans la lecture
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)
Mise à jour 2017
Pas besoin d'aller sur github, il est sur PyPi sous un autre nom :
pip3 install --user python-magic
# or:
sudo apt install python3-magic # Ubuntu distro package
Le code peut également être simplifié :
>>> import magic
>>> magic.from_file('/tmp/img_3304.jpg', mime=True)
'image/jpeg'
Liaisons Python à libmagic
Toutes les différentes réponses sur ce sujet sont très confuses, j'espère donc donner un peu plus de clarté avec cet aperçu des différentes liaisons de libmagic.Auparavant, mammadori avait donné un réponse courte listant l’option disponible.
libmagique
- nom du module :
magic
- Pypi : fichier-magie
- source: https://github.com/file/file/tree/master/python
Lors de la détermination du type MIME d'un fichier, l'outil de choix est simplement appelé file
et son back-end s'appelle libmagic
.(Voir le Page d'accueil du projet.) Le projet est développé dans un référentiel CVS privé, mais il existe un miroir git en lecture seule sur github.
Maintenant, cet outil, dont vous aurez besoin si vous souhaitez utiliser l'une des liaisons libmagic avec python, est déjà livré avec ses propres liaisons python appelées file-magic
.Il n'y a pas beaucoup de documentation dédiée à ces derniers, mais vous pouvez toujours jeter un oeil à la page de manuel de la c-library : man libmagic
.L'utilisation de base est décrite dans le fichier Lisez-moi:
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)
En dehors de cela, vous pouvez également utiliser la bibliothèque en créant un Magic
objet utilisant magic.open(flags)
comme le montre le fichier exemple.
Les deux toivotuo et ewr2san les utilise file-magic
fixations incluses dans le file
outil.Ils supposent à tort qu'ils utilisent le python-magic
emballer. Cela semble indiquer que si les deux file
et python-magic
sont installés, le module python magic
fait référence à l'ancien.
python-magie
- nom du module :
magic
- Pypi : python-magie
- source: https://github.com/ahupp/python-magic
C'est la bibliothèque dont parle Simon Zimmermann dans sa réponse et qui est également employé par Claude COULOMBÉ ainsi que Gringo suave.
fichiermagique
- nom du module :
magic
- Pypi : fichiermagique
- source: https://github.com/aliles/filemagic
Note:Ce projet a été mis à jour pour la dernière fois en 2013 !
En raison du fait qu'elle est basée sur la même c-api, cette bibliothèque présente certaines similitudes avec file-magic
inclus dans libmagic
.Il n'est mentionné que par maman et aucune autre réponse ne l'emploie.
Le module MIMEtypes reconnaît simplement un type de fichier en fonction de son extension.Si vous essayez de récupérer un type de fichier sans extension, les types MIME ne fonctionneront pas.
J'ai essayé beaucoup d'exemples mais avec Django mutagène joue bien.
Exemple vérifiant si les fichiers sont mp3
from mutagen.mp3 import MP3, HeaderNotFoundError
try:
audio = MP3(file)
except HeaderNotFoundError:
raise ValidationError('This file should be mp3')
L'inconvénient est que votre capacité à vérifier les types de fichiers est limitée, mais c'est un excellent moyen si vous souhaitez non seulement vérifier le type de fichier, mais également accéder à des informations supplémentaires.
C'est peut-être déjà ancien, mais pourquoi ne pas utiliser UploadedFile.content_type directement depuis Django ?Ce n'est pas la même chose?(https://docs.djangoproject.com/en/1.11/ref/files/uploads/#django.core.files.uploadedfile.UploadedFile.content_type)
Pour les données de type de tableau d'octets, vous pouvez utiliser magic.from_buffer (_byte_array, mime = true)
J'essaie d'abord la bibliothèque de types MIME.Si cela ne fonctionne pas, j'utilise plutôt la bibliothèque 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
vous pouvez utiliser imghdr Module Python.