2014-06-24 40 views
5

Używam zapytań Pythona, aby opublikować żądanie. Gdy parametr attachment ma kilka znaków spoza ASCII, zgłaszany jest wyjątek, przy innych okazjach, w których istnieją tylko dane ASCII, wszystko jest w porządku.python żąda problemów z nazwami plików 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 []         
       ) 

redaguje: Po dekodowaniu nazwę pliku z utf8, nie rozumiem jednak wyjątek plik nie jest podłączony. I debugowany żądań załączeniem pliku ze znaków ASCII tylko w swoim imieniu, a żądanie nagłówki żądania zbudować to:

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

powiedzie to, dostaję pocztę z załącznikami.

Jednak, gdy za pomocą pliku z hebrajskimi literami, nagłówek wniosek jest:

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

dostaję pocztę ale bez pliku dołączonym do niego. Jakieś pomysły?

+0

Pokaż nam śledzenie błędów. Dostarczone zdjęcie pokazuje, że są pewne próby utworzenia nagłówka z nieoczekiwanymi znakami. Ale może to być przypadek dla wielu wartości, które masz w swoim kodzie, a stacktrace powie nam więcej. Idealnie powinieneś podać krótki fragment kodu, który uruchamia się i pokazuje problem. Obecnie nie można wiele powielić. –

Odpowiedz

3

Gdy nazwa pliku zawiera non-ascii, biblioteka żądań koduje go zgodnie ze standardem RFC 2231. Format jest taki, jaki widziałeś: filename*=utf-8''....... Wydaje się, że MailGun nie obsługuje tego standardu, w wyniku czego nazwy plików spoza ascii zostały utracone. Możesz skontaktować się z MailGun, aby potwierdzić, jakiego formatu oczekują nazwy plików w Unicode.

Jako nie-idealne obejście, można zastąpić spoza ASCII znaki jak:

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

I jawnie określić nazwę pliku podczas wywoływania żądania jako (zakładamy attachments jest lista nazw plików unicode-based):

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

edytuje

Jeśli chcesz dostosować format nagłówka, załóżmy (zamiast o f standardem RFC 2231) MailGun może zaakceptować tego formatu:

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

Następnie można dostosować nazwy plików jak:

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

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

zależności od odpowiedzi MailGun użytkownika, może się zdarzyć, że trzeba dostosować kody requests lub użyj zamiast tego bibliotek niskiego poziomu (urllib2). Mam nadzieję, że mogą one obsłużyć RFC 2231

+0

Już to robię, problemem jest to, że plik nie przechodzi z jakiegoś powodu ... nie ma wyjątków (zobacz w sekcji edycji). Zaktualizuję kod w pytaniu, aby uniknąć nieporozumień. –

+0

Dzięki, sprawdzę z mailGun. Jeśli tak, to jak mogę wymuszać żądania, aby traktować nazwy plików w Unicode w taki sposób, jaki stwierdza mailGun? –

+0

Dzięki, będzie czekać na odpowiedź mailgun –