Petr Baudis
Petr Baudis

Reputation: 1198

How to send emails with names in headers from Python

I need to send nice-looking emails from Python with address headers that contain names - somehow something that never pops up in tutorials.

I'm using email.mime.text.MIMEText() to create the email, but setting msg['To'] = 'á <[email protected]>' rather than utf8-encoding only the name part, will utf8-encode the whole header value, which of course fails miserably. How to do this correctly?

I have found a sort-of solution Python email module: form header "From" with some unicode name + email but it feels hard to accept such a hack, since there does seem to be some support for handling this automatically in Python's email package in email.headerregistry which should be used automatically as far as I can see, but it doesn't happen.

Upvotes: 2

Views: 842

Answers (1)

zvone
zvone

Reputation: 19352

You have to use the right policy from email.policy to get the correct behaviour.

Wrong Policy

email.message.Message will use email.policy.Compat32 by default. That one was designed for backward-compatibility wih older Python versions and does the wrong thing:

>>> msg = email.message.Message(policy=email.policy.Compat32())
>>> msg['To'] = 'ššššš <[email protected]>'
>>> msg.as_bytes()
b'To: =?utf-8?b?xaHFocWhxaHFoSA8c3Nzc0BleGFtcGxlLmNvbT4=?=\n\n'

Correct Policy

email.policy.EmailPolicy will do what you want:

>>> msg = email.message.Message(policy=email.policy.EmailPolicy())
>>> msg['To'] = 'ššššš <[email protected]>'
>>> msg.as_bytes()
b'To: =?utf-8?b?xaHFocWhxaHFoQ==?= <[email protected]>\n\n'

Python 2.7

With older Python versions (eg 2.7), you have to use the "hack" as you called it:

>>> msg = email.message.Message()
>>> msg['To'] = email.header.Header(u'ššššš').encode() + ' <[email protected]>'
>>> msg.as_string()
'To: =?utf-8?b?xaHFocWhxaHFoQ==?= <[email protected]>\n\n'

Upvotes: 4

Related Questions