Introduction

Aspose.Email FOSS for Python (aspose-email-foss) is a MIT-licensed Python library for working with Outlook MSG files, RFC-5322 EML messages, and Compound File Binary (CFB) storage structures. The library requires no native extensions and installs directly from PyPI with pip install aspose-email-foss.

The package targets Python 3.10 and later. It implements the MSG message format and the underlying CFB container format from scratch, giving deterministic control over how messages are serialized and read across Windows, macOS, Linux, and containerized environments.

This page covers the key feature areas: MSG creation and reading, EML interoperability, MAPI property access, attachment and recipient management, and low-level CFB storage operations.


Key Features

Creating MSG Files

MapiMessage.create() constructs a new MAPI message from a subject string and a plain-text body string. After construction, set typed MAPI properties through set_property() using the PropertyId enum, add recipients with add_recipient(), and attach binary data with add_attachment(). Call save() to write the result to disk or to_bytes() to get the raw bytes.

from aspose.email_foss import msg

message = msg.MapiMessage.create(
    "Quarterly status update",
    "Please review the attached summary.",
)
message.set_property(msg.PropertyId.SENDER_NAME, "Build Agent")
message.set_property(msg.PropertyId.SENDER_EMAIL_ADDRESS, "build.agent@example.com")
message.set_property(msg.PropertyId.INTERNET_MESSAGE_ID, "<report-001@example.com>")

message.add_recipient("alice@example.com", display_name="Alice")
message.add_attachment("summary.txt", b"Q2 metrics attached.", mime_type="text/plain")
message.save("quarterly.msg")

Reading MSG Files

Load an existing .msg file with MapiMessage.from_file(). The returned object exposes subject, body, and other typed attributes. Use iter_attachments_info() to iterate over attachment metadata and iter_properties() to walk all MAPI properties on the message.

from aspose.email_foss import msg

loaded = msg.MapiMessage.from_file("quarterly.msg")
print(loaded.subject)
print(loaded.body)

for attachment in loaded.iter_attachments_info():
    print(attachment.filename)

loaded.close()

Converting MSG to EML and Back

to_email_message() converts a MapiMessage into a standard Python email.message.EmailMessage object, preserving subject, sender, recipients, body, and attachments. Serialize the result with as_bytes() to obtain EML-format bytes suitable for SMTP delivery or archival.

The reverse direction — building a MapiMessage from an EmailMessage — uses MapiMessage.from_email_message().

from aspose.email_foss import msg

# MSG → EML
loaded = msg.MapiMessage.from_file("quarterly.msg")
eml = loaded.to_email_message()
with open("quarterly.eml", "wb") as f:
    f.write(eml.as_bytes())
loaded.close()

# EML → MSG
from email.message import EmailMessage

source = EmailMessage()
source["Subject"] = "Meeting notes"
source["From"] = "alice@example.com"
source["To"] = "bob@example.com"
source.set_content("Notes from today's standup.")

mapi = msg.MapiMessage.from_email_message(source)
mapi.save("meeting-notes.msg")

MAPI Property Access

set_property() and get_property_value() provide typed access to MAPI properties using the PropertyId enum. iter_properties() returns all properties as MapiProperty objects, each exposing a property_id, property_type, and value.

from aspose.email_foss import msg

message = msg.MapiMessage.from_file("quarterly.msg")
for prop in message.iter_properties():
    print(hex(prop.property_id), prop.property_type, repr(prop.value)[:60])
message.close()

Common PropertyId values include SUBJECT, SENDER_NAME, SENDER_EMAIL_ADDRESS, INTERNET_MESSAGE_ID, MESSAGE_DELIVERY_TIME, BODY, and BODY_HTML.

Attachment and Recipient Management

add_attachment() accepts a filename string, raw bytes, and an optional MIME type. For embedding an existing MapiMessage as an attachment, use add_embedded_message_attachment(). add_recipient() accepts an email address and an optional display name and recipient type (RECIPIENT_TYPE_TO, RECIPIENT_TYPE_CC, RECIPIENT_TYPE_BCC).

from aspose.email_foss import msg

message = msg.MapiMessage.create("Project handoff", "Files are attached.")
message.set_property(msg.PropertyId.SENDER_EMAIL_ADDRESS, "sender@example.com")

message.add_recipient("lead@example.com", display_name="Tech Lead")
message.add_recipient(
    "backup@example.com",
    display_name="Backup",
    recipient_type=msg.RECIPIENT_TYPE_CC,
)
message.add_attachment("spec.pdf", b"%PDF-1.4 ...", mime_type="application/pdf")
message.save("handoff.msg")

Low-Level CFB Container Access

The library includes a standalone CFB layer for reading and writing Compound File Binary containers independently of MAPI. CFBReader.from_file() loads any .msg or .cfb file and exposes its directory entries. iter_storages() and iter_streams() enumerate the container tree; get_stream_data() extracts raw stream bytes.

from aspose.email_foss import msg

reader = msg.CFBReader.from_file("quarterly.msg")
print(f"CFB version={reader.major_version} sector_size={reader.sector_size}")
print(f"Directory entries: {reader.directory_entry_count}")

for entry in reader.iter_streams():
    data = reader.get_stream_data(entry.stream_id)
    print(f"Stream: {entry.name!r}  size={len(data)}")

reader.close()

Quick Start

pip install aspose-email-foss
from aspose.email_foss import msg

# Create a message
message = msg.MapiMessage.create("Hello from Python", "This is the message body.")
message.set_property(msg.PropertyId.SENDER_EMAIL_ADDRESS, "sender@example.com")
message.add_recipient("recipient@example.com", display_name="Recipient")
message.save("hello.msg")

# Read it back and convert to EML
with msg.MapiMessage.from_file("hello.msg") as loaded:
    eml = loaded.to_email_message()
    print("Subject:", eml["Subject"])
    print("From:", eml["From"])

Supported Formats

FormatExtensionReadWrite
MSG.msg
CFB.cfb
EML.eml

MSG files are read via MapiMessage.from_file(). EML is accessed through the from_email_message() / to_email_message() bridge. CFB containers are handled directly by CFBReader.


Open Source & Licensing

Aspose.Email FOSS for Python is released under the MIT License. The source is available on GitHub and the package is distributed via PyPI under the name aspose-email-foss. MIT licensing permits use in commercial applications without royalty or attribution requirements beyond license text inclusion.


Getting Started