email.header: سرآیندهای بینالمللیسازیشده¶
کد منبع: Lib/email/header.py
این ماژول بخشی از API ایمیل قدیمی (Compat32) است. در API کنونی، کدگذاری و کدگشایی سرآیندها بهصورت شفاف توسط API دیکشنریمانند کلاس EmailMessage انجام میشود. علاوه بر استفاده در کد قدیمی، این ماژول میتواند در برنامههایی که نیاز دارند مجموعههای نویسهای را که هنگام کدگذاری سرآیندها استفاده میشوند بهطور کامل کنترل کنند، مفید باشد.
متن باقیمانده در این بخش، مستندات اصلی ماژول است.
RFC 2822 استاندارد پایهای است که قالب پیامهای ایمیل را توصیف میکند. این استاندارد برگرفته از استاندارد قدیمیتر RFC 822 است که در زمانی بهطور گستردهای استفاده میشد که بیشتر ایمیلها فقط از نویسههای ASCII تشکیل شده بودند. RFC 2822 مشخصاتی است که با این فرض نوشته شده است که ایمیل فقط شامل نویسههای ASCII هفتبیتی است.
البته، از آنجا که ایمیل در سراسر جهان گسترش یافته است، بینالمللی شده است، بهطوری که اکنون میتوان از مجموعهنویسههای مختص هر زبان در پیامهای ایمیل استفاده کرد. استاندارد پایه همچنان نیاز دارد که پیامهای ایمیل فقط با نویسههای ASCII هفتبیتی منتقل شوند، بنابراین RFCهای متعددی نوشته شدهاند که نحوهی کدگذاری ایمیل حاوی نویسههای غیر ASCII به قالب سازگار با RFC 2822 را توصیف میکنند. این RFCها شامل RFC 2045، RFC 2046، RFC 2047 و RFC 2231 هستند. بستهی email از این استانداردها در ماژولهای email.header و email.charset پشتیبانی میکند.
اگر میخواهید نویسههای غیر ASCII را در سرآیندهای ایمیل خود بگنجانید، مثلاً در فیلدهای Subject یا To، باید از کلاس Header استفاده کنید و فیلد را در شیء Message به نمونهای از Header اختصاص دهید، بهجای آنکه برای مقدار سرآیند از یک رشته استفاده کنید. کلاس Header را از ماژول email.header ایمپورت کنید. برای مثال:
>>> from email.message import Message
>>> from email.header import Header
>>> msg = Message()
>>> h = Header('p\xf6stal', 'iso-8859-1')
>>> msg['Subject'] = h
>>> msg.as_string()
'Subject: =?iso-8859-1?q?p=F6stal?=\n\n'
Notice here how we wanted the Subject field to contain a non-ASCII
character? We did this by creating a Header instance and passing in
the character set to use when encoding it. When the subsequent
Message instance was flattened, the Subject
field was properly RFC 2047 encoded. MIME-aware mail readers would show this
header using the embedded ISO-8859-1 character.
در اینجا توضیح کلاس Header آمده است:
- class email.header.Header(s=None, charset=None, maxlinelen=None, header_name=None, continuation_ws=' ', errors='strict')¶
یک سرآیند سازگار با MIME ایجاد کنید که بتواند حاوی رشتههایی در مجموعهنویسههای مختلف باشد.
آرگومان اختیاری s، مقدار اولیهی سرآیند است. اگر
None(پیشفرض) باشد، مقدار اولیهی سرآیند تنظیم نمیشود. میتوانید بعداً با فراخوانیهای متدappend()به سرآیند اضافه کنید. s ممکن است یک نمونه ازbytesیاstrباشد، اما برای معناییات، مستنداتappend()را ببینید.charset اختیاری دو هدف دارد: این آرگومان همان معنای آرگومان charset در متد
append()را دارد. همچنین مجموعه نویسهی پیشفرض را برای تمام فراخوانیهای بعدیappend()که در آنها آرگومان charset ذکر نشده است، تنظیم میکند. اگر charset در سازنده ارائه نشود (پیشفرض)، مجموعه نویسهیus-asciiهم بهعنوان مجموعه نویسه اولیهی s و هم بهعنوان پیشفرض برای فراخوانیهای بعدیappend()استفاده میشود.میتوان حداکثر طول خط را بهصورت صریح از طریق maxlinelen مشخص کرد. برای شکستن خط اول به طول کوتاهتر (برای در نظر گرفتن سرآیند فیلد که در s لحاظ نشده است، مثلاً Subject)، نام فیلد را در header_name وارد کنید. مقدار پیشفرض maxlinelen برابر ۷۸ است و مقدار پیشفرض header_name برابر
Noneاست، به این معنا که برای خط اولِ یک سرآیند طولانیِ شکستهشده در نظر گرفته نمیشود.continuation_ws اختیاری باید فضای خالی برای تا کردن سطرهای (folding whitespace) سازگار با RFC 2822 باشد، و معمولاً یا یک فاصله است یا یک نویسهی تب سخت (hard tab). این نویسه به ابتدای سطرهای ادامه افزوده میشود. مقدار پیشفرض continuation_ws یک نویسهی فاصله است.
آرگومان اختیاری errors مستقیماً به متد
append()ارسال میشود.- append(s, charset=None, errors='strict')¶
رشتهی s را به سرآیند MIME میافزاید.
charset اختیاری، در صورت داده شدن، باید نمونهای از
Charset(ببینیدemail.charset) یا نام یک مجموعهی نویسه باشد، که به نمونهای ازCharsetتبدیل خواهد شد. مقدارNone(پیشفرض) به این معناست که charset دادهشده در سازنده استفاده میشود.s میتواند نمونهای از
bytesیاstrباشد. اگر نمونهای ازbytesباشد، آنگاه charset کدگذاری آن رشته بایتی است، و اگر رشته نتواند با آن مجموعه نویسه کدگشایی شود،UnicodeErrorپرتاب خواهد شد.اگر s نمونهای از
strباشد، آنگاه charset راهنمایی است که مجموعه نویسههای موجود در رشته را مشخص میکند.در هر یک از این دو حالت، هنگام تولید سرآیندی مطابق با RFC 2822 با استفاده از قوانین RFC 2047، رشته با کدک خروجی مجموعهنویسه کدگذاری میشود. اگر رشته با کدک خروجی قابل کدگذاری نباشد، یک UnicodeError پرتاب خواهد شد.
اگر s یک رشته بایتی باشد، errors اختیاری بهعنوان آرگومان errors به فراخوانی decode ارسال میشود.
- encode(splitchars=';, \t', maxlinelen=None, linesep='\n')¶
کدگذاری یک سرآیند پیام در قالبی مطابق با RFC، احتمالاً با شکستن سطرهای طولانی و بستهبندی بخشهای غیر ASCII در کدگذاریهای base64 یا quoted-printable.
splitchars اختیاری، رشتهای است شامل نویسههایی که الگوریتم شکستن باید در جریان شکستن عادی سطرهای سرایند، وزن بیشتری به آنها بدهد. این موضوع، پشتیبانی بسیار تقریبی از «شکستهای نحوی سطح بالاتر» در RFC 2822 است: هنگام شکستن سطرهای، نقاط شکستی که پیش از آنها یک نویسهی شکست قرار دارد، ترجیح داده میشوند و نویسهها به همان ترتیبی که در رشته ظاهر میشوند، ترجیح داده میشوند. فاصله و تب میتوانند در رشته گنجانده شوند تا مشخص شود که در صورت نبودن سایر نویسههای شکست در سطری که شکسته میشود، باید به کدامیک بهعنوان نقطهی شکست ترجیح داده شود. Splitchars بر سطرهای کدگذاریشدهی RFC 2047 تأثیری ندارد.
اگر داده شود، maxlinelen مقدار نمونه برای حداکثر طول خط را نادیده میگیرد.
linesep نویسههای استفادهشده برای جدا کردن سطرهای سرآیند تاشده را مشخص میکند. مقدار پیشفرض آن مفیدترین مقدار برای کد برنامه پایتون (
\n) است، اما میتوان\r\nرا مشخص کرد تا سرآیندهایی با جداکنندههای خط منطبق با RFC تولید شوند.تغییر یافته در نسخهی 3.2: آرگومان linesep افزوده شد.
کلاس
Headerهمچنین تعدادی متد برای پشتیبانی از عملگرهای استاندارد و توابع توکار فراهم میکند.- __str__()¶
Returns an approximation of the
Headeras a string, using an unlimited line length. All pieces are decoded using the specified encoding and joined together appropriately. Any pieces with a charset of'unknown-8bit'are decoded as ASCII using the'replace'error handler.تغییر یافته در نسخهی 3.2: پشتیبانی از مجموعهنویسهی
'unknown-8bit'افزوده شد.
ماژول email.header همچنین توابع کاربردی زیر را فراهم میکند.
- email.header.decode_header(header)¶
یک مقدار سرآیند پیام را بدون تبدیل مجموعه نویسه کدگشایی کنید. مقدار سرآیند در header قرار دارد.
به دلایل تاریخی، این تابع ممکن است یکی از این دو مورد را برگرداند:
فهرستی از جفتها که شامل هر یک از بخشهای کدگشاییشدهی سرآیند است،
(decoded_bytes, charset)، که در آن decoded_bytes همیشه یک نمونه ازbytesاست و charset یکی از موارد زیر است:رشتهای با حروف کوچک که شامل نام مجموعهی نویسهی مشخصشده است.
Noneبرای بخشهای کدگذارینشدهی سرآیند.
فهرستی به طول ۱ شامل یک جفت
(string, None)، که در آن string همیشه نمونهای ازstrاست.
هنگامی که خطاهای کدگشایی خاصی رخ میدهند (برای مثال، یک استثنای کدگشایی base64)، ممکن است
email.errors.HeaderParseErrorپرتاب شود.در اینجا مثالهایی آمده است:
>>> from email.header import decode_header >>> decode_header('=?iso-8859-1?q?p=F6stal?=') [(b'p\xf6stal', 'iso-8859-1')] >>> decode_header('unencoded_string') [('unencoded_string', None)] >>> decode_header('bar =?utf-8?B?ZsOzbw==?=') [(b'bar ', None), (b'f\xc3\xb3o', 'utf-8')]
توجه
این تابع فقط برای سازگاری با نسخههای قدیمیتر وجود دارد. برای کد جدید، توصیه میکنیم از
email.headerregistry.HeaderRegistryاستفاده کنید.
- email.header.make_header(decoded_seq, maxlinelen=None, header_name=None, continuation_ws=' ')¶
یک نمونه
Headerرا از دنبالهای از جفتها، همانگونه که توسطdecode_header()برگردانده میشود، ایجاد کنید.decode_header()یک رشته مقدار سرآیند را میگیرد و دنبالهای از جفتها در قالب(decoded_string, charset)برمیگرداند که charset نام مجموعه نویسهها است.این تابع یکی از آن دنبالههای جفتها را میگیرد و یک نمونه
Headerرا برمیگرداند. آرگومانهای اختیاری maxlinelen، header_name و continuation_ws همانند سازندهیHeaderهستند.توجه
این تابع فقط برای سازگاری با نسخههای قبلی وجود دارد و استفاده از آن در کد جدید توصیه نمیشود.