Introduction

Parsing email messages programmatically is a common requirement for data migration, archival workflows, and compliance tools. Outlook MSG files use the Compound File Binary (CFB) container format with MAPI properties to encode message metadata, body content, recipients, and attachments. Working with this format in Python has traditionally required either commercial libraries or low-level binary manipulation.

The aspose-email-foss package provides a pure-Python, MIT-licensed library for reading, creating, and converting Outlook MSG files. It exposes a high-level MapiMessage API for common tasks alongside lower-level MsgReader access for detailed inspection of the underlying CFB structure. The library requires Python 3.10 or later and has no native dependencies.

Whether you need to extract the subject line and body from a batch of archived messages, enumerate attachments for indexing, or convert MSG files to standard RFC 5322 format, this library handles the binary parsing so you can focus on your application logic.


What’s Included

Reading MSG Files with MapiMessage

The MapiMessage class is the primary entry point for parsing Outlook MSG files. Open a file, access its properties, and close it cleanly with a context manager.

from aspose.email_foss import msg

with msg.MapiMessage.from_file("meeting-invite.msg") as message:
    print(f"Subject: {message.subject}")
    print(f"Body: {message.body[:200]}")
    print(f"HTML body available: {message.body_html is not None}")

The from_file method reads the CFB container, parses the MAPI property streams, and populates typed attributes. The subject, body, and body_html properties return decoded strings directly.

Extracting Recipients

Every MSG file stores recipient information in dedicated MAPI storages. The MapiMessage.recipients property returns a list of MapiRecipient objects with typed fields for display name, email address, and recipient type (TO, CC, or BCC).

from aspose.email_foss import msg

with msg.MapiMessage.from_file("team-update.msg") as message:
    for recipient in message.recipients:
        print(
            f"{recipient.display_name} <{recipient.email_address}> "
            f"type={recipient.recipient_type}"
        )

Working with Attachments

The iter_attachments_info method yields MapiAttachment objects that provide the filename, raw bytes, MIME type, and optional Content-ID for inline images.

from aspose.email_foss import msg

with msg.MapiMessage.from_file("report.msg") as message:
    for att in message.iter_attachments_info():
        print(f"  {att.filename} ({att.mime_type}, {len(att.data)} bytes)")
        if att.content_id:
            print(f"    inline content-id: {att.content_id}")

Accessing MAPI Properties

For scenarios that require specific MAPI property values beyond the convenience attributes, use get_property_value with a PropertyId constant. This provides direct access to any property stored in the MSG file.

from aspose.email_foss import msg

with msg.MapiMessage.from_file("notification.msg") as message:
    sender = message.get_property_value(msg.PropertyId.SENDER_NAME)
    email = message.get_property_value(msg.PropertyId.SENDER_EMAIL_ADDRESS)
    delivery = message.get_property_value(msg.PropertyId.MESSAGE_DELIVERY_TIME)
    print(f"From: {sender} <{email}>")
    print(f"Delivered: {delivery}")

Iterating All Properties

When you need to inspect every property in a message (for debugging, auditing, or migration), the iter_properties method yields MapiProperty objects with full tag and value information.

from aspose.email_foss import msg

with msg.MapiMessage.from_file("sample.msg") as message:
    for prop in message.iter_properties():
        print(
            f"tag=0x{prop.property_tag:08X} "
            f"type=0x{prop.property_type:04X} "
            f"value={prop.value!r}"
        )

Converting MSG to EML

The to_email_message method converts a parsed MSG into a standard Python email.message.EmailMessage object. From there you can serialize the message to RFC 5322 (EML) format using the standard library.

from aspose.email_foss import msg

with msg.MapiMessage.from_file("archive.msg") as message:
    email_message = message.to_email_message()
    eml_bytes = email_message.as_bytes()
    with open("archive.eml", "wb") as f:
        f.write(eml_bytes)

Note that EML output uses Python’s built-in email module for serialization. The library handles the MSG-to-MAPI-to-EmailMessage conversion; the standard library handles the RFC 5322 wire format.


Quick Start

Install the package from PyPI and parse your first MSG file in under 20 lines:

# Install: pip install aspose-email-foss>=26.3
from aspose.email_foss import msg

# Create a new message
message = msg.MapiMessage.create(
    "Project status update",
    "Hello team,\n\nPlease review the attached report.\n\nRegards",
)
message.add_recipient("alice@example.com", display_name="Alice")
message.add_attachment("notes.txt", b"meeting notes\n", mime_type="text/plain")
message.save("status-update.msg")

# Read it back and extract data
with msg.MapiMessage.from_file("status-update.msg") as loaded:
    print(f"Subject: {loaded.subject}")
    print(f"Recipients: {len(loaded.recipients)}")
    for att in loaded.iter_attachments_info():
        print(f"Attachment: {att.filename} ({len(att.data)} bytes)")

Supported Formats

FormatExtensionReadWrite
Outlook MSG.msgYesYes
Compound File Binary.cfbYesYes
EML (via conversion).emlYes (via from_email_message)Yes (via to_email_message)

EML support works through conversion: MapiMessage.from_email_message() imports from a Python email.message.EmailMessage object, and to_email_message() exports back. Direct EML file parsing is not provided — the standard library handles the EML wire format.


Open Source & Licensing

Aspose.Email FOSS for Python is released under the MIT license. You are free to use, modify, and distribute the library in both commercial and non-commercial projects. The full source code is available on GitHub.

The library is a pure-Python implementation with no compiled extensions or native dependencies. It runs on any platform that supports Python 3.10 or later.


Getting Started

Explore more resources for working with Aspose.Email FOSS for Python: