Domanda

Supponiamo che tu voglia salvare un gruppo di file da qualche parte, ad esempio nei BLOB.Supponiamo che tu voglia distribuire questi file tramite una pagina Web e fare in modo che il client apra automaticamente l'applicazione/visualizzatore corretto.

Assunzione:Il browser capisce quale applicazione/visualizzatore utilizzare dall'intestazione mime-type (content-type?) nella risposta HTTP.

Sulla base di questo presupposto, oltre ai byte del file, vuoi salvare anche il tipo MIME.

Come troveresti il ​​tipo MIME di un file?Attualmente utilizzo un Mac, ma dovrebbe funzionare anche su Windows.

Il browser aggiunge queste informazioni quando pubblica il file sulla pagina web?

Esiste una libreria Python ordinata per trovare queste informazioni?Un WebService o (meglio ancora) un database scaricabile?

È stato utile?

Soluzione

Il metodo python-magic suggerito da toivotuo è obsoleto. La magia di Python il trunk attuale è su Github e in base al file readme lì, trovare il tipo MIME, viene fatto in questo modo.

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

Altri suggerimenti

IL modulo mimetypes nella libreria standard determinerà/indovinerà il tipo MIME da un'estensione di file.

Se gli utenti stanno caricando file, il post HTTP conterrà il tipo MIME del file insieme ai dati.Ad esempio, Django rende disponibili questi dati come attributo del file File caricato oggetto.

Un modo più affidabile rispetto all'utilizzo della libreria mimetypes sarebbe utilizzare il pacchetto python-magic.

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

Ciò equivarrebbe a utilizzare file(1).

Su Django si potrebbe anche assicurarsi che il tipo MIME corrisponda a quello di UploadedFile.content_type.

Questo sembra essere molto 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)

Per favore, riferisci Vecchia posta

Esistono 3 diverse librerie che racchiudono libmagic.

2 di questi sono disponibili su pypi (quindi l'installazione pip funzionerà):

  • filemagic
  • python-magico

E un altro, simile a python-magic, è disponibile direttamente negli ultimi sorgenti libmagic, ed è quello che probabilmente hai nella tua distribuzione Linux.

In Debian il pacchetto python-magic riguarda questo ed è usato come ha detto toivotuo e non è obsoleto come ha detto Simon Zimmermann (IMHO).

Mi sembra un'altra versione (dell'autore originale di libmagic).

Peccato che non sia disponibile direttamente su pypi.

in Python 2.6:

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

Non hai indicato quale server web stavi utilizzando, ma Apache ha un modulo carino chiamato Magia del mimo che utilizza per determinare il tipo di file quando gli viene detto di farlo.Legge parte del contenuto del file e cerca di capire di che tipo è in base ai caratteri trovati.E come Menzionato Dave Webb IL Modulo MimeType sotto Python funzionerà, a condizione che un'estensione sia a portata di mano.

In alternativa, se sei seduto su una macchina UNIX puoi usare sys.popen('file -i ' + fileName, mode='r') per acquisire il tipo MIME.Windows dovrebbe avere un comando equivalente, ma non sono sicuro di cosa sia.

Il metodo di @toivotuo ha funzionato meglio e in modo più affidabile per me con Python3.Il mio obiettivo era identificare i file gzippati che non hanno un'estensione .gz affidabile.Ho installato 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))

per un file gzippato restituisce:applicazione/gzip;set di caratteri=binario

per un file txt decompresso (dati iostat):testo/semplice;charset=us-ascii

per un file tar:applicazione/x-tar;set di caratteri=binario

per un file bz2:applicazione/x-bzip2;set di caratteri=binario

e ultimo ma non meno importante per me un file .zip:applicazione/zip;set di caratteri=binario

In Python 3.x e webapp con l'URL del file che non può avere un'estensione o un'estensione falsa.Dovresti installare python-magic, usando

pip3 install python-magic

Per Mac OS X, dovresti installare anche libmagic usando

brew install libmagic

Frammento di codice

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)

in alternativa potresti inserire una dimensione nel file 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)

Aggiornamento 2017

Non c'è bisogno di andare su github, è su PyPi con un nome diverso:

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

Il codice può anche essere semplificato:

>>> import magic

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

Collegamenti Python a libmagic

Tutte le diverse risposte su questo argomento sono molto confuse, quindi spero di fare un po’ più di chiarezza con questa panoramica dei diversi legami di libmagic.In precedenza mammadori ha dato a risposta breve elencando l'opzione disponibile.

libmagic

Quando si determina il tipo MIME di un file, viene semplicemente chiamato lo strumento scelto file e viene chiamato il suo back-end libmagic.(Vedi il Home page del progetto.) Il progetto è sviluppato in un repository cvs privato, ma esiste un file Mirror git di sola lettura su github.

Ora questo strumento, di cui avrai bisogno se desideri utilizzare uno qualsiasi dei collegamenti libmagic con Python, viene già fornito con i propri collegamenti Python chiamati file-magic.Non c'è molta documentazione dedicata a loro, ma puoi sempre dare un'occhiata alla pagina man della c-library: man libmagic.L'utilizzo di base è descritto nel file leggimi:

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)

Oltre a questo, puoi anche utilizzare la libreria creando un file Magic oggetto utilizzando magic.open(flags) come mostrato nel file di esempio.

Entrambi toivotuo ed ewr2san usali file-magic attacchi inclusi nel file attrezzo.Presumono erroneamente di utilizzare il file python-magic pacchetto. Ciò sembra indicare che se entrambi file E python-magic sono installati, il modulo Python magic si riferisce al precedente.

python-magico

Questa è la biblioteca di cui parla Simon Zimmermann la sua risposta e che è anche impiegato da Claude COULOMBE così come Gringo Suave.

filemagic

Nota:Questo progetto è stato aggiornato l'ultima volta nel 2013!

Poiché è basata sullo stesso c-api, questa libreria presenta alcune somiglianze con file-magic incluso in libmagic.Viene menzionato solo da mammadori e nessun'altra risposta lo utilizza.

Il modulo mimetypes riconosce semplicemente un tipo di file in base all'estensione del file.Se proverai a recuperare un tipo di file senza estensione, i tipi MIME non funzioneranno.

Ho provato molti esempi ma con Django mutageno gioca bene.

Esempio di verifica se i file lo sono mp3

from mutagen.mp3 import MP3, HeaderNotFoundError  

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

Lo svantaggio è che la tua capacità di controllare i tipi di file è limitata, ma è un ottimo modo se desideri non solo controllare il tipo di file ma anche accedere a informazioni aggiuntive.

Potrebbe essere già vecchio, ma perché non utilizzare UploadedFile.content_type direttamente da Django?Non è lo stesso?(https://docs.djangoproject.com/en/1.11/ref/files/uploads/#django.core.files.uploadedfile.UploadedFile.content_type)

Per i dati del tipo di array di byte è possibile utilizzare magic.from_buffer (_Byte_array, mime = true)

Provo prima la libreria dei tipi MIME.Se non funziona, utilizzo invece la libreria 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

Puoi usare imghdr Modulo Python.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top