Batu Lab NotesPractical developer guides

Parse a Content-Type header with email.message

By Batu ยท English technical notes

The email package can parse MIME-style headers even when the input is a small, synthetic message rather than an email sent over a network. This example gives HeaderParser a Content-Type header followed by the required blank line that ends the header block. The resulting message object provides get_content_type, get_content_charset, and get_param to read the normalized media type, the charset parameter, and a custom profile parameter.

The concrete input spells the media type as Application/JSON, but get_content_type() returns the lower-case value application/json. The assertions capture that normalization and confirm that quoted parameter values are returned without their surrounding quotes. HeaderParser is suitable when only headers matter; it defaults to header-only parsing. The parser APIs shown are available in Python 3.3 and later, and this explicit policy.default form is suitable for Python 3.6 and later.

A parsed header is not proof that a body is JSON, that its declared charset matches body bytes, or that an arbitrary profile URI is acceptable. Invalid or absent Content-Type values can fall back to a default type, so callers that require a particular declaration should inspect the original header and define rejection rules explicitly.

See the official email.parser documentation and email.message documentation. AI assistance disclosure: this article was drafted with AI assistance and should be adapted to the message format your application accepts.

from email import policy
from email.parser import HeaderParser


raw_headers = (
    'Content-Type: Application/JSON; charset="utf-8"; '
    'profile="https://example.test/v1"\n'
    "\n"
)
message = HeaderParser(policy=policy.default).parsestr(raw_headers)

assert message.get_content_type() == "application/json"
assert message.get_content_charset() == "utf-8"
assert message.get_param("profile") == "https://example.test/v1"

print(f"type={message.get_content_type()}")
print(f"charset={message.get_content_charset()}")
print(f"profile={message.get_param('profile')}")
type=application/json
charset=utf-8
profile=https://example.test/v1