PDF из другого API поврежден после преобразования и отправки электронной почты через Sendgrid

#python #base64 #sendgrid

# #python #base64 #sendgrid

Вопрос:

Я работал с API, который отправляет двоичный файл запрошенного PDF. Я хотел отправить его по электронной почте в виде вложения через SendGrid, но у меня постоянно возникают проблемы.

До сих пор я пробовал:

  • Используя его напрямую, не кодируя то, что когда-либо. Результат: поврежденный файл.
  • Посмотрите в документе Sendgrid. Согласно Sendgrid, содержимое должно быть «содержимым вложения в кодировке Base64».
  • Пробовал как base64.b64encode (attachment_data), так и binascii.b2a_base64 (attachment_data). Результат: ошибка UnicodeEncodeError: кодек ‘ascii’ не может кодировать символы в позиции 10-13: порядковый номер не в диапазоне (128)
  • Попробовал тип (attachment_data), который выводит «тип ‘unicode’ «.
  • Пробовал как base64.b64encode(attachment_data.encode («utf-8»)), так и binascii.b2a_base64(attachment_data.encode («utf-8»)). Результат: поврежден файл, в котором указано: «Adobe Acrobat Reader DC не удалось открыть ‘property_info.pdf’, поскольку это либо не поддерживаемый тип файла, либо файл был поврежден (например, он был отправлен как вложение электронной почты и неправильно декодирован)».

Я нахожу некоторые вопросы и ответы как в Stackoverflow, так и в собственном Python Github от SendGrid, но, похоже, он в основном работает с файлом pdf, а не с двоичными данными. Кажется, что большинство просто говорит «закодируйте его в utf-8», но в этом случае он просто поврежден. Любые подсказки о том, что еще я могу сделать, чтобы отправить файл правильно?

Вот функция, которая выполняет Sendgrid:

 def to_sendgrid(my_email, other_email, text, attachment_data):
    subject = "Sample pdf attached."
    from_email = Email(my_email)
    to_email = Email(other_email)
    content = Content("text/plain", text)
    mail = Mail(from_email, subject, to_email, content)
    attachment_data = base64.b64encode(attachment_data.encode("utf-8"))
    attachment = Attachment()
    attachment.set_content(attachment_data)
    attachment.set_type("application/pdf")
    attachment.set_filename("sample.pdf")
    attachment.set_disposition("attachment")
    attachment.set_content_id("Sample")
    mail.add_attachment(attachment)

    try:
        sendgrid_client.client.mail.send.post(request_body=mail.get())
    except Exception as e:
        print str(e)
 

Комментарии:

1. тип содержимого должен быть application/octet-stream; — можете ли вы поделиться только той частью кода, которую вы написали, если это не сработает. Если этот тип содержимого не работает, application/pdf это должно помочь более простым почтовым клиентам. — случайно отправлено без этого последнего предложения. Возможно, это связано с вашей проблемой ascii, используете ли вы Windows? Если да, возможно, это может помочь pypi.python.org/pypi/win_unicode_console

2. Ранее я использовал application / pdf. Я только что попробовал это с octet-stream, но все равно получаю поврежденный pdf. Я собираюсь отредактировать свой пост, чтобы показать код. Я использую Mac.

3. как вы открываете файл? open("path to file", "rb") или просто open("path to file") .encode («utf-8»), вероятно, повреждает данные pdf. Аналогичный эффект для вас, когда вы берете HTML <a>Some anchor</a> -файл и конвертируете его в amp;<aamp;>Some anchoramp;</aamp;>

4. Ранее я пытался использовать open (attachment_data, «rb»), и я только что попробовал open (attachment_data) сейчас. В обоих случаях я получил сообщение об ошибке «TypeError: file() аргумент 1 должен быть закодированной строкой без нулевых байтов, а не в юникоде».

5. Похоже, что здесь происходит гораздо больше ошибок, чем просто проблема с API SendGrid. open — это псевдоним для file, а аргумент one — строка пути к исходному файлу pdf. если attachment_data является содержимым PDF-файла, он не будет работать — docs.python.org/2/library/functions.html#open Я бы порекомендовал вам попробовать спросить reddit.com/r/learnpython за помощью.