Registry / data / extract-msg

extract-msg

JSON →
library0.56.1pypypi✓ verified 29d ago

extract-msg is a Python library designed to parse and extract emails and their attachments from Microsoft Outlook's proprietary .msg files. It supports various MSG file formats, including embedded messages and complex structures, and can handle different encodings. The library is actively maintained with frequent minor and patch releases, currently at version 0.55.0.

pip install extract-msg
INSTALL
IMPORT
SIG · EXTRACT-MSG
E
extract-msg
datapythonv0.56.1
Install
4.6s avg
Import
1288ms
Disk
47MB
Pass rate
10/ 10
Env Coverage10 / 10
glibc
3.9–3.13
musl
3.9–3.13
Install & Compatibility
Where this runs
tested against v0.56.1 · pip install
no network on importno background threads
Install × environment matrix
Each cell = how many times install + import succeeded across repeated harness runs. Partial = flaky.
glibc = Debian/Ubuntu slim · musl = Alpine Linux
musl
py 3.10–3.95 runs
installs and imports cleanly · install 0.0s · import 1.338s · 47.9MB
glibc
py 3.10–3.95 runs
installs and imports cleanly · install 4.6s · import 1.238s · 48MB
47MB installed
● package 47MB
Code
Verified usage

Verified import paths — ran on the pinned version, not inferred.

Message
✓ from extract_msg import Message

This quickstart demonstrates how to open an MSG file, access its subject, sender, date, and body, and save any attached files. It uses a context manager (`with Message(...) as msg:`) to ensure proper resource handling.

import os from extract_msg import Message # Create a dummy .msg file for demonstration # In a real scenario, you'd replace 'example.msg' with your actual file path # This part is just to make the example runnable without an actual .msg file present initially # A real .msg file structure is complex and cannot be simply created like this. # Assume 'example.msg' exists and contains an Outlook message. # For testing, you might use a pre-existing sample .msg file. msg_file_path = 'example.msg' if not os.path.exists(msg_file_path): # This part would typically be replaced by pointing to an actual .msg file. # For a truly runnable example, one would need a sample .msg file. print(f"Please create a file named '{msg_file_path}' containing a valid Outlook .msg email to run this example.") print("Using a placeholder for demonstration purposes.") # Exit or handle gracefully if no .msg file is found for testing. # For this example, we'll proceed assuming it will fail, or a real file exists. try: with Message(msg_file_path) as msg: print(f"Subject: {msg.subject}") print(f"Sender: {msg.sender}") print(f"Date: {msg.date}") print(f"Body (plain text):\n{msg.body[:200]}...") # Print first 200 chars if msg.attachments: print(f"\nAttachments found: {len(msg.attachments)}") output_dir = 'attachments_output' os.makedirs(output_dir, exist_ok=True) for attachment in msg.attachments: filename = attachment.longFilename or attachment.shortFilename if filename: try: attachment.save(customPath=output_dir, raw=False) print(f" Saved attachment: {filename}") except Exception as e: print(f" Error saving attachment {filename}: {e}") else: print("\nNo attachments.") except FileNotFoundError: print(f"Error: The file '{msg_file_path}' was not found. Please ensure it exists.") except Exception as e: print(f"An error occurred while processing the MSG file: {e}")
Debug
Known issues
gotchaThe default `maxNameLength` for filenames when saving attachments or message data has changed from 256 to 40 characters in version 0.55.0. If you relied on longer filenames by default, your saved files might now be truncated.
fix
Explicitly set `maxNameLength` in `attachment.save()` or `MessageBase.save()` methods if you require longer filenames, e.g., `attachment.save(maxNameLength=256)`.
affects: >=0.55.0
breakingThe prepared HTML output (e.g., via `msg.htmlBody`) changed in version 0.54.0 to use plainly encoded HTML instead of a prettified format. If your application parsed or relied on the structure of the prettified HTML, this change may affect you.
fix
Adjust your HTML parsing logic to account for the change to plain HTML. If prettification is desired, you may need to apply a separate HTML prettifier (e.g., `BeautifulSoup`) after extraction.
affects: >=0.54.0
gotchaPrior to version 0.55.0, if `openMsg()` or `Message` (when opening specific OLE files that weren't standard MSG) was used without a context manager (`with...as`), the underlying OLE file handle might not be closed, leading to resource leaks. While `openMsg()` was fixed internally in 0.55.0, it's a good practice to always use context managers.
fix
Always use the `with Message(...) as msg:` context manager pattern to ensure files are properly closed and resources are released, even if the file is a plain OLE file. If you are manually handling `MSGFile` objects, ensure `close()` is called.
affects: <0.55.0 (for `openMsg`), all versions (for best practice)
gotchaEncoding issues, particularly with child/embedded MSG files and their interaction with the parent's encoding, have been a source of bugs (e.g., fixed in v0.54.1, v0.52.0). While fixes are implemented, be aware that complex nested MSG structures or malformed files can still present encoding challenges.
fix
Ensure your environment's locale settings are appropriate for the expected encodings. Report specific malformed files to the library maintainers if issues persist after updating to the latest version. The library continuously improves its handling of diverse encodings.
affects: All versions (potential for edge cases with malformed files)
Errors
Common errors & fixes
ModuleNotFoundError: No module named 'extract_msg'
The `extract-msg` library has not been installed or is not accessible in the current Python environment.
fix
Install the library using pip: `pip install extract-msg`
AttributeError: module 'extract_msg' has no attribute 'Message'
This error usually occurs when attempting to call `extract_msg.Message()` directly, which is often an internal class, or due to API changes between versions. The recommended public API for opening MSG files is `extract_msg.openMsg()`.
fix
Use the `openMsg` function instead: `import extract_msg; msg = extract_msg.openMsg('path/to/your/file.msg')`
UnicodeDecodeError: 'charmap' codec can't decode byte 0x... in position ...: character maps to <undefined>
This error arises when `extract-msg` attempts to decode text from an MSG file using an incorrect character encoding (often the system's default, like 'charmap' or 'utf-8') that doesn't match the file's actual encoding. MSG files can contain various encodings.
fix
When opening the message, specify the correct encoding if known, or try common encodings like 'latin-1' or 'cp1252'. You can also use error handling to ignore problematic characters: `msg = extract_msg.openMsg('path/to/file.msg', overrideEncoding='cp1252', errors='ignore')` or `msg = extract_msg.openMsg('path/to/file.msg', errors='replace')`
NotImplementedError: Current version of extract_msg does not support extraction of containers that are not embedded msg files.
This specific error indicates that the library encountered an attachment type within the MSG file that it does not currently support for extraction (e.g., certain OLE objects or non-MSG/EML container types).
fix
While direct support for all container types might not be implemented, you can handle this by wrapping the attachment extraction in a try-except block to skip unsupported attachments: `for attachment in msg.attachments: try: attachment.save() except NotImplementedError: print(f'Skipping unsupported attachment: {attachment.longFilename}')`
Upgrade
Version history
0.56.1latest on PyPI · released Aug 14, 2026
Audit
Dependencies

No dependency data recorded yet.

Agent activity
27 hits · last 30 days
node
24
Resources
extract-msg — pip install extract-msg · libregistry