242 votes

Comment trouver le type mime d'un fichier en python ?

Supposons que vous souhaitiez enregistrer un ensemble 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 l'application/le visualiseur approprié.

Assomption : Le navigateur détermine l'application/le visualiseur à utiliser en fonction de l'en-tête mime-type (content-type ?) de la réponse HTTP.

En partant de cette hypothèse, en plus des octets du fichier, vous voulez également enregistrer le type MIME.

Comment trouver le type MIME d'un fichier ? Je suis actuellement sur un Mac, mais cela devrait également fonctionner sur Windows.

Le navigateur ajoute-t-il cette information lors de l'affichage du fichier sur la page web ?

Existe-t-il une bibliothèque python pour trouver ces informations ? Un service Web ou (encore mieux) une base de données téléchargeable ?

269voto

Simon Zimmermann Points 1239

La méthode python-magique suggérée par toivotuo est dépassée. La magie de Python Le tronc actuel est sur Github et d'après le readme, la recherche du type MIME se fait comme suit.

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

19 votes

Merci pour le commentaire ! veuillez noter que "au-dessus" est un concept difficile dans stackoverflow, puisque l'ordre est groupé par votes et ordonné aléatoirement à l'intérieur des groupes. Je suppose que vous faites référence à la réponse de @toivotuo.

1 votes

Oui, je n'ai pas \t avoir assez de "points" pour créer des commentaires au moment où j'écris cette réponse. Mais j'aurais probablement dû l'écrire en tant que commentaire, afin que le @toivotuo puisse modifier sa question.

1 votes

Rpm -qf /usr/lib/python2.7/site-packages/magic.py -i URL : darwinsys.com/file Résumé : Liaisons Python pour l'API libmagic rpm -qf /usr/bin/file -i Nom : fichier URL : darwinsys.com/file python-magic de darwinsys.com/file et qui est livré avec Linux Fedora fonctionne comme l'a dit @toivotuo. Et semble plus main stream.

115voto

Dave Webb Points 90034

El module mimetypes de la bibliothèque standard détermine/ devine le type MIME à partir de l'extension d'un fichier.

Si les utilisateurs téléchargent des fichiers, le message HTTP contiendra le type MIME du fichier à côté des données. Par exemple, Django rend ces données disponibles en tant qu'attribut de la balise Fichier téléchargé objet.

14 votes

Si les fichiers sont stockés dans des BLOBs, comme indiqué dans la question, vous ne pouvez pas connaître l'extension du fichier.

0 votes

N'oubliez pas non plus d'aseptiser les fichiers si vous les transmettez à d'autres utilisateurs : stackoverflow.com/questions/1745743/

70 votes

Les extensions de fichiers ne sont pas un moyen fiable de déterminer le type mime.

52voto

toivotuo Points 339

Un moyen plus fiable que d'utiliser la bibliothèque mimetypes serait d'utiliser le paquet python-magic.

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

Ceci serait équivalent à l'utilisation de file(1).

Sur Django, on peut aussi s'assurer que le type MIME correspond à celui de UploadedFile.content_type.

2 votes

Voir le billet de Simon Zimmermann pour une utilisation actualisée de python-magic.

0 votes

@DarenThomas : Comme mentionné dans la réponse de mammadori, cette réponse est pas dépassée et distincte de la solution de Simon Zimmermann. Si vous avez l'utilitaire de fichier installé, vous pouvez probablement utiliser cette solution. Elle fonctionne pour moi avec file-5.32. Sur gentoo, vous devez également avoir activé le drapeau USE de python pour le paquet file.

48voto

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)

Veuillez vous référer à Vieux poste

Mise à jour - Dans la version python 3+, c'est plus pratique maintenant :

import mimetypes
print(mimetypes.guess_type("sample.html"))

5 votes

Je ne pense pas que l'urllib soit nécessaire dans votre exemple.

5 votes

Pour Python 3.X remplacer import urllib par from urllib import request. Et ensuite utiliser "request" au lieu de urllib

1 votes

Fonctionne également pour python 2.7

10voto

apito Points 123

Dans python 2.6 :

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

7 votes

Cela n'est pas nécessaire, puisque le file n'est en fait qu'une enveloppe autour de libmagic. Vous pouvez tout aussi bien utiliser la liaison python (python-magic), comme dans la réponse de Simon.

7 votes

Cela dépend du système d'exploitation. Sous Mac OS X, par exemple, vous avez "file" mais pas libmagic dans l'environnement normal.

0 votes

Cela ne me semble pas sûr, PATH devrait être échappé. Je ne connais pas l'équivalent Python, mais les développeurs php utiliseraient Popen("/usr/bin/file --mime ".escapeshellarg(PATH)); - par exemple, votre code échouerait sur les fichiers contenant des nouvelles lignes ou des guillemets, et probablement aussi $dollarsign, mais il vous protégerait aussi contre les pirates qui feraient PATH='; rm -rfv / et une telle injection de coquille

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X