Introduction

Aspose.Email FOSS for Python is now available on PyPI: a free, MIT-licensed library for creating, reading, and converting Outlook .msg files entirely in Python, with no dependency on Microsoft Office or any native extension. Install it with pip install aspose-email-foss>=26.3 and start working with MSG and CFB containers immediately.

The library targets Python 3.10 and later. It implements the Compound File Binary (CFB) format and the MSG message format from scratch, giving you deterministic control over how email messages are serialized and read. Because the implementation is pure Python, it runs identically on Windows, macOS, Linux, and in containerized environments.

Aspose.Email FOSS is designed for developers building email processing pipelines, compliance archival tools, forensic analysis workflows, or any application that needs to create or inspect Outlook-compatible message files without a running Exchange or Outlook installation.


Key Features

Create MSG Files

Build Outlook-compatible .msg files from scratch using MapiMessage.create(). Set standard MAPI properties like subject, sender, delivery time, and display fields through the PropertyId enum. Add recipients with add_recipient() and file attachments with add_attachment(), then save the result to disk.

from aspose.email_foss import msg

message = msg.MapiMessage.create(
    "Quarterly status update and rollout plan",
    "Hello team,\n\nPlease find the latest rollout summary attached.\n\nRegards,\nEngineering",
)

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, "<example-001@example.com>")

message.add_recipient("alice@example.com", display_name="Alice Example")
message.add_recipient("bob@example.com", display_name="Bob Example")
message.add_recipient(
    "carol@example.com",
    display_name="Carol Example",
    recipient_type=msg.RECIPIENT_TYPE_CC,
)

message.add_attachment("hello.txt", b"sample attachment\n", mime_type="text/plain")
message.save("example-message.msg")

Read and Convert MSG to EML

Load an existing .msg file with MapiMessage.from_file() and convert it to a standard Python EmailMessage object via to_email_message(). From there, serialize to EML bytes for storage or forwarding through SMTP.

from aspose.email_foss import msg

with msg.MapiMessage.from_file("example-message.msg") as loaded:
    email_message = loaded.to_email_message()
    eml_bytes = email_message.as_bytes()

with open("example-message.eml", "wb") as f:
    f.write(eml_bytes)

Inspect MSG Internals

Use MsgReader and its underlying CFBReader to inspect the binary structure of an MSG file. Access CFB metadata (version, sector size, directory entry count) and iterate over MAPI property entries at the binary level.

from aspose.email_foss import msg

reader = msg.MsgReader.from_file("example-message.msg")
cfb = reader.cfb_reader

print(f"CFB major_version={cfb.major_version}")
print(f"sector_size={cfb.sector_size}")
print(f"directory_entries={cfb.directory_entry_count}")

for entry in reader.iter_top_level_fixed_length_properties():
    tag = entry.property_tag
    print(f"tag=0x{tag:08X} flags=0x{entry.flags:08X} value={entry.value.hex()}")

reader.close()

Low-Level CFB Access

Read and traverse any Compound File Binary container using CFBReader. Enumerate storages and streams, resolve paths by name, and extract raw stream data for custom processing.

from aspose.email_foss.cfb import CFBReader

reader = CFBReader.from_file("example-message.msg")

for entry in reader.iter_storages():
    print(f"Storage: {entry.name}")

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

reader.close()

Quick Start

Install the library and create your first MSG file in under ten lines:

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

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

with msg.MapiMessage.from_file("hello.msg") as loaded:
    eml = loaded.to_email_message()
    print(eml["Subject"])

Supported Formats

FormatImportExport
MSGYesYes
CFBYesYes

Open Source & Licensing

Aspose.Email FOSS for Python is released under the MIT License. You may use it in personal, internal, and commercial projects without restriction. The source code is available on GitHub.


Getting Started