2014-06-24 10 views
5

Sto usando le richieste python per pubblicare una richiesta. quando il parametro allegato ha alcuni caratteri non ascii viene sollevata un'eccezione, in altre occasioni in cui esistono solo dati ascii, tutto va bene.python richiede problemi con nomi di file non ascii

you can see the exception here

response = requests.post(url="https://api.mailgun.net/v2/%s/messages" % utils.config.mailDomain, 
       auth=("api", utils.config.mailApiKey), 
       data={ 
         "from" : me, 
         "to" : recepients, 
         "subject" : subject, 
         "html" if html else "text" : message 
        }, 

       files= [('attachment', codecs.open(f.decode('utf8'))) for f in attachments] if attachments and len(attachments) else []         
       ) 

Modifiche: Dopo la decodifica il nome del file con utf8, non ottengo un'eccezione tuttavia il file non è collegato. Ho debug richieste con allegare un file con i caratteri ASCII solo nel suo nome, e la richiesta intestazioni richieste build è:

{'Content-Type': None, 'Content-Location': None, 'Content-Disposition': u'form-data; name="attachment"; filename="Hello.docx"'} 

Questo successo, sto ricevendo la posta con gli allegati.

Tuttavia, quando si utilizza un file con caratteri ebraici, intestazione della richiesta è:

{'Content-Type': None, 'Content-Location': None, 'Content-Disposition': 'form-data; name="attachment"; filename*=utf-8\'\'%D7%91%D7%93%D7%99%D7%A7%D7%94.doc'} 

ricevo la posta, ma senza il file allegato ad esso. Qualche idea?

+0

Mostraci la traccia di errore. L'immagine che fornisci mostra alcuni tentativi di creare un'intestazione con caratteri imprevisti. Ma questo può essere il caso di più valori che hai nel tuo codice e Stacktrace ci dirà di più. Idealmente dovresti fornire un breve pezzo di codice, che esegue e mostra il problema. Attualmente non è possibile riprodurre molto. –

risposta

3

Quando il nome file contiene non-ascii, la libreria di richieste lo codifica in base allo standard RFC 2231. Il formato è come quello che hai visto: filename*=utf-8''....... Sembra che MailGun non supporti questo standard, di conseguenza, i nomi dei file non ascii sono andati persi. Puoi contattare MailGun per verificare quale formato si aspettano per i nomi di file unicode.

Come una soluzione non-perfetto, è possibile sostituire caratteri non-ASCII come:

def replace_non_ascii(x): return ''.join(i if ord(i) < 128 else '_' for i in x) 

E specificare esplicitamente il nome del file al momento della chiamata richieste come (assumere attachments è l'elenco dei nomi di file basati su Unicode):

files= [('attachment', (replace_non_ascii(f), codecs.open(f))) for f in attachments] ... 

modifiche

Se si desidera personalizzare il formato dell'intestazione, supponiamo (al posto o f serie RFC 2231) MailGun può accettare questo tipo di formato:

filename="%D7%91%D7%93%D7%99%D7%A7%D7%94.doc" 

Quindi è possibile personalizzare i nomi di file come:

import urllib 
def custom_filename(x): return urllib.quote(x.encode('utf8')) 

files= [('attachment', (custom_filename(f), codecs.open(f))) for f in attachments] ... 

A seconda della risposta del MailGun, può essere possibile che avete bisogno di modificare i codici di requests o utilizzare invece librerie di basso livello (urllib2). Speriamo che possano supportare RFC 2231

+0

Lo sto già facendo, il problema è che il file non viene eseguito per qualche motivo ... non c'è eccezione (vedi nella sezione delle modifiche). Aggiornerò il codice nella domanda per evitare confusioni anche –

+0

Grazie, controllerò con mailGun. In questo caso, come posso forzare le richieste a trattare nomi di file unicode come afferma mailGun? –

+0

Grazie, aspetterò la risposta di mailgun –

Problemi correlati