2013-04-02 31 views
10

voglio per ottenere la dimensione di caricare un'immagine per controllare se è maggiore di file di massimo caricare limit.I provato questo:Flask: ottenere la dimensione di oggetto request.files

@app.route("/new/photo",methods=["POST"]) 
def newPhoto(): 

    form_photo = request.files['post-photo'] 
    print form_photo.content_length 

E 'stampato 0 Dove sto sbagliando? Dovrei trovare la dimensione di questa immagine dal percorso temporaneo di esso? Non c'è niente come PHP $_FILES['foo']['size'] in Python?

risposta

17

Ci sono alcune cose da tenere presente qui - la proprietà CONTENT_LENGTH sarà la lunghezza del contenuto del caricamento di file come segnalato dal browser, ma sfortunatamente molti browser non lo inviano, come indicato nello docs e source.

Come per l'errore TypeError, la prossima cosa da tenere presente è che i caricamenti di file inferiori a 500 KB sono archiviati in memoria come StringIO object, anziché essere spoolati su disco (consultare di nuovo quei documenti), quindi la tua chiamata di statistiche avrà esito negativo.

MAX_CONTENT_LENGTH è il modo corretto per rifiutare i caricamenti di file più grandi di quanto si desideri e, se ne avete bisogno, l'unico modo affidabile per determinare la lunghezza dei dati è di capirlo dopo aver gestito il caricamento - o stat il file dopo che hai .save() d esso:

request.files['file'].save('/tmp/foo') 
size = os.stat('/tmp/foo').st_size 

Oppure, se non si utilizza il disco (ad esempio la memorizzazione in un database), contare i byte che hai letto:

blob = request.files['file'].read() 
size = len(blob) 

Anche se ovviamente stai attento non stai leggendo troppo d ata nella memoria se il MAX_CONTENT_LENGTH è molto grande

+0

Ok, grazie per la risposta – saidozcan

+1

non è meglio http://stackoverflow.com/a/23601025/125507? cerchi solo la fine del file e non stai usando alcuna memoria? – endolith

8

Il modo corretto per impostare un limite massimo di caricamento del file è tramite la configurazione dell'app MAX_CONTENT_LENGTH. Ad esempio, se si desidera impostare un limite di upload di 16 megabyte, si dovrebbe effettuare le seguenti operazioni per la configurazione app:

app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024 

Se il file caricato è troppo grande, Flask tornerà automaticamente codice di stato 413 Request Entity Too Grande - questo dovrebbe essere gestito dal lato del cliente.

+1

Okay, questo è un buon modo. Non c'è ancora un modo per ottenere le dimensioni dell'immagine? – saidozcan

+0

questo è buono a meno che il tuo sistema non sia su una piccola unità e vuoi che l'utente carichi qualsiasi dimensione di file a meno che non superi lo spazio libero. in questo caso, usa il file.seek() suggerito da Steely Wing – andrei

1

Come qualcun altro ha già suggerito, è necessario utilizzare il

app.config['MAX_CONTENT_LENGTH'] 

per limitare le dimensioni dei file. Ma Dal momento che specificamente vuole scoprire la dimensione dell'immagine, si può fare:

import os 
photo_size = os.stat(request.files['post-photo']).st_size 
print photo_size 
+3

Ora dice TypeError: coercizione a Unicode: bisogno di stringhe o buffer, FileStorage trovato. Cosa dovrei fare? – saidozcan

+0

'request.files' non contiene percorsi. – ThiefMaster

10

Se non si desidera salvare il file su disco prima, utilizzare il seguente codice, questo lavoro in funzione in memoria

import os 

file = request.files['file'] 
file.seek(0, os.SEEK_END) 
file_length = file.tell() 

altrimenti, questo sarà meglio

request.files['file'].save('/tmp/file') 
file_length = os.stat('/tmp/file').st_size 
+0

'file.seek (0, 2)' dovrebbe fare la stessa cosa senza importare 'os'? http://stackoverflow.com/a/283719/125507 cerca fino a 0 byte dalla fine del file – endolith

2

la seguente sezione del codice dovrebbe soddisfare il vostro scopo ..

 

form_photo.seek(0,2) 
size = form_photo.tell() 

Problemi correlati