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.
The library addresses a common Python development gap: reading and writing Outlook .msg
files without requiring a running Outlook installation or proprietary SDK. It also exposes
the full CFB container format that underlies .msg files, making it suitable for tasks
ranging from message migration to storage inspection.
The library ships with a typed API surface covering MAPI message construction, recipient and attachment management, property serialization, and CFB document round-trips.
Key Features
Creating and Serializing MSG Files
MapiMessage.create() constructs a new MAPI message from a subject and body string.
From there you can add typed properties, recipients, and binary attachments, then serialize
the result to bytes using to_bytes().
import datetime
from aspose.email_foss.msg.mapi_message import MapiMessage, PropertyId
message = MapiMessage.create("Quarterly Report", "Please review the attached report.")
message.set_property(PropertyId.SENDER_NAME, "Alice")
message.set_property(PropertyId.SENDER_EMAIL_ADDRESS, "alice@example.com")
message.set_property(
PropertyId.MESSAGE_DELIVERY_TIME,
datetime.datetime(2026, 3, 15, 10, 30, tzinfo=datetime.timezone.utc),
)
message.add_recipient("bob@example.com", display_name="Bob")
message.add_attachment("report.pdf", b"%PDF-1.4 ...", mime_type="application/pdf")
raw_bytes = message.to_bytes()
Reading Existing MSG Files
MapiMessage.from_file() reads an existing .msg file from disk. You can also reconstruct
a message from raw bytes by passing a CFBReader through MsgReader and MsgDocument.
from aspose.email_foss.msg.mapi_message import MapiMessage
from aspose.email_foss.msg.reader import MsgReader, MsgDocument
from aspose.email_foss.cfb.reader import CFBReader
# Read from file path
msg = MapiMessage.from_file("message.msg")
print(msg.subject)
# Or reconstruct from bytes
msg2 = MapiMessage.from_msg_document(
MsgDocument.from_reader(MsgReader(CFBReader(raw_bytes)))
)
print(msg2.subject)
for att in msg2.attachments:
print(att.filename, len(att.data), "bytes")
Converting Between MAPI and RFC-5322 EML
MapiMessage.from_email_message() converts a standard Python email.message.EmailMessage
object into a MAPI message, preserving subject, recipients, body, and attachments.
The reverse conversion uses to_email_message().
from email.message import EmailMessage
from aspose.email_foss.msg.mapi_message import MapiMessage
# Build a standard Python email
eml = EmailMessage()
eml["Subject"] = "Meeting notes"
eml["From"] = "alice@example.com"
eml["To"] = "bob@example.com"
eml.set_content("Notes from today's meeting.")
# Convert to MAPI and serialize as .msg
mapi = MapiMessage.from_email_message(eml)
with open("meeting-notes.msg", "wb") as f:
f.write(mapi.to_bytes())
# Round-trip back to EML
recovered = mapi.to_email_message()
print(recovered["Subject"])
Compound File Binary (CFB) Storage
The library includes a standalone CFB layer (CFBReader, CFBWriter, CFBDocument,
CFBStorage, CFBStream) for reading and writing the Compound File Binary format
independently of MAPI. This is useful for inspecting the raw storage structure of
.msg files or for building custom compound file containers.
from aspose.email_foss.cfb.writer import CFBWriter, CFBDocument, CFBStorage, CFBStream
from aspose.email_foss.cfb.reader import CFBReader
# Build a CFB document with nested storage
root = CFBStorage("Root Entry")
root.add_stream(CFBStream("Metadata", b"meta-payload"))
nested = root.add_storage(CFBStorage("Attachments"))
nested.add_stream(CFBStream("Attachment1", b"binary-content"))
doc = CFBDocument(root=root, major_version=3)
data = CFBWriter.to_bytes(doc)
# Read it back
reader = CFBReader(data)
entry = reader.resolve_path(["Attachments", "Attachment1"])
print(reader.get_stream_data(entry.stream_id))
MAPI Property Access
iter_properties() returns all MAPI properties on a message as MapiProperty objects.
Named properties (PidLidTag and PidNameTag) are accessible via MapiNamedProperty.
MapiPropertyCollection provides dict-like property access.
from aspose.email_foss.msg.mapi_message import MapiMessage
msg = MapiMessage.from_file("message.msg")
for prop in msg.iter_properties():
print(hex(prop.property_id), prop.property_type, repr(prop.value)[:60])
Quick Start
pip install aspose-email-fossimport datetime
from aspose.email_foss.msg.mapi_message import MapiMessage, PropertyId
from aspose.email_foss.msg.reader import MsgReader, MsgDocument
from aspose.email_foss.cfb.reader import CFBReader
# Create a message
message = MapiMessage.create("Hello", "This is the body.")
message.set_property(PropertyId.SENDER_NAME, "Sender")
message.set_property(PropertyId.SENDER_EMAIL_ADDRESS, "sender@example.com")
message.add_recipient("recipient@example.com", display_name="Recipient")
message.add_attachment("note.txt", b"attachment content", mime_type="text/plain")
# Serialize and reload
raw = message.to_bytes()
reloaded = MapiMessage.from_msg_document(
MsgDocument.from_reader(MsgReader(CFBReader(raw)))
)
email = reloaded.to_email_message()
print("Subject:", email["Subject"])
print("From:", email["From"])
Supported Formats
| Format | Extension | Read | Write |
|---|---|---|---|
| Msg | .msg | ✓ | ✓ |
| CFB | .cfb | ✓ | ✓ |
| eml | .eml | ✓ | ✓ |
MSG files are read via MapiMessage.from_file() and MsgReader. EML is accessed through
the from_email_message() / to_email_message() conversion bridge. CFB containers are
handled directly by CFBReader and CFBWriter.
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 inclusion.