2014-06-24 4 views
5

Ich verwende Python-Anfragen, um eine Anfrage zu stellen. Wenn der Attachment-Parameter einige nicht-ASCII-Zeichen hat, wird eine Exception ausgelöst, in anderen Fällen, in denen nur Ascii-Daten existieren, ist alles in Ordnung.Python fordert Probleme mit nicht ASCII-Dateinamen an

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 []         
       ) 

EDITS: die Dateinamen mit UTF-8 Nach der Decodierung, ich eine Ausnahme nicht jedoch die Datei angehängt ist, nicht erhalten. ich gedebuggt Anfragen mit einer Datei mit nur ASCII-Zeichen im Namen angebracht wird, und die Request-Header-Anfragen bauen ist:

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

Dies gelingt, bin ich die E-Mail mit den Anlagen zu bekommen.

Wenn jedoch eine Datei mit hebräischen Buchstaben verwenden, die Kopfzeile der Anfrage ist:

{'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'} 

ich die Mail bekommen, aber ohne die Datei angefügt. Irgendwelche Ideen?

+0

Zeigen Sie uns die Fehlerspur. Das von Ihnen angegebene Bild zeigt, dass versucht wird, eine Kopfzeile mit unerwarteten Zeichen zu erstellen. Aber das kann ein Fall für mehrere Werte sein, die Sie in Ihrem Code haben, und Stacktrace würde uns mehr erzählen. Idealerweise sollten Sie ein kurzes Stück Code angeben, das läuft und das Problem aufzeigt. Derzeit ist es nicht möglich, viel zu reproduzieren. –

Antwort

3

Wenn der Dateiname Nicht-ASCII enthält, codiert die Bibliothek der Anforderung den Standard RFC 2231. Das Format ist wie das, was Sie gesehen haben: filename*=utf-8''....... Scheint, dass der MailGun diesen Standard nicht unterstützt, als Ergebnis sind nicht-ASCII-Dateinamen verloren gegangen. Sie können MailGun kontaktieren, um zu bestätigen, welches Format für Unicode-Dateinamen erwartet wird.

Als nicht-perfekte Abhilfe können Sie nicht-ASCII-Zeichen als Ersatz:

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

Und explizit Dateinamen angeben, wenn Anforderungen als (unter der Annahme attachments ist Liste der Unicode-basierten Dateinamen) Aufruf:

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

EDITS

Wenn Sie die Header-Format anpassen wollen, nehmen wir an (statt o f-Standard RFC 2231) MailGun können diese Art von Format annehmen:

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

Dann können Sie Dateinamen wie anpassen:

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

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

auf Antwort des MailGun Abhängig kann es möglich sein, dass Sie zwicken müssen Codes requests oder verwenden Sie stattdessen Low-Level-Bibliotheken (urllib2). Hoffentlich können sie unterstützen RFC 2231

+0

Ich mache das schon, das Problem ist, dass die Datei aus irgendeinem Grund nicht durchläuft ... Es gibt keine Ausnahme (siehe im Abschnitt "Bearbeiten"). Ich werde den Code in der Frage aktualisieren, um Verwirrungen auch zu vermeiden –

+0

Danke, ich werde mit mailGun überprüfen. Wenn dies der Fall ist, wie kann ich Anfragen erzwingen, Unicode-Dateinamen so zu behandeln, wie mailGun angibt? –

+0

Danke, werde auf die Antwort der Mailgun warten –