2014-06-24 17 views
5

Tôi đang sử dụng yêu cầu python để đăng yêu cầu. khi tham số đính kèm có một số ký tự ascii không phải là ngoại lệ được nêu ra, trong những trường hợp khác chỉ có dữ liệu ascii tồn tại, mọi thứ đều ổn.python yêu cầu các vấn đề với tên tệp ascii không

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

CHỈNH SỬA: Sau khi giải mã tên tập tin với utf8, tôi không nhận được một ngoại lệ tuy nhiên các tập tin không được đính kèm. tôi sửa lỗi yêu cầu với gắn một tập tin với các nhân vật chỉ ascii trong tên của nó, và yêu cầu tiêu đề yêu cầu xây dựng là:

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

này thành công, tôi nhận được mail với các file đính kèm.

Tuy nhiên, khi sử dụng một tập tin với các nhân vật tiếng Hebrew, header của request là:

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

tôi nhận được thư nhưng không có tập tin gắn liền với nó. Bất kỳ ý tưởng?

+0

Hiển thị cho chúng tôi dấu vết lỗi. Hình ảnh bạn cung cấp cho thấy, có một số nỗ lực để tạo ra một tiêu đề với các ký tự không mong muốn. Nhưng điều này có thể là một trường hợp cho nhiều giá trị bạn có trong mã của bạn và stacktrace sẽ cho chúng tôi biết thêm. Lý tưởng nhất là bạn nên cung cấp đoạn mã ngắn, chạy và hiển thị vấn đề. Hiện tại không thể tái sản xuất nhiều. –

Trả lời

3

Khi tên tệp không chứa ascii, thư viện yêu cầu mã hóa theo tiêu chuẩn RFC 2231. Định dạng giống như những gì bạn đã thấy: filename*=utf-8''....... Có vẻ như MailGun không hỗ trợ tiêu chuẩn này, kết quả là, tên tập tin không phải ascii đã bị mất. Bạn có thể liên hệ với MailGun để xác nhận định dạng nào họ mong đợi đối với tên tệp unicode.

Là một workaround không hoàn hảo, bạn có thể thay thế ký tự phi ascii như:

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

Và xác định rõ ràng tên tập tin khi gọi yêu cầu như (giả attachments là danh sách các tên tập tin unicode-based):

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

cÁC cHỈNH SỬA

Nếu bạn muốn tùy chỉnh các định dạng tiêu đề, chúng ta hãy giả định (thay vì o f chuẩn RFC 2231) MailGun thể chấp nhận loại định dạng:

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

Sau đó, bạn có thể tùy chỉnh tên tập tin như:

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

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

Tùy thuộc vào phản ứng MailGun, nó có thể được có thể là bạn cần phải tinh chỉnh quy tắc ứng requests hoặc sử dụng thư viện cấp thấp (urllib2) thay thế. Hy vọng rằng họ có thể hỗ trợ RFC 2231

+0

Tôi đã làm điều đó, vấn đề là các tập tin không đi qua vì một số lý do ... không có ngoại lệ (xem trong phần chỉnh sửa). Tôi sẽ cập nhật mã trong câu hỏi để tránh nhầm lẫn cũng –

+0

Cảm ơn, tôi sẽ kiểm tra với mailGun. Nếu đây là trường hợp, làm thế nào tôi có thể buộc các yêu cầu để xử lý các tên tập tin unicode cách mailGun tiểu bang? –

+0

Cảm ơn, sẽ chờ phản hồi của mailgun –

Các vấn đề liên quan