parsedmarc

raw JSON →
9.10.3 verified Mon Apr 27 auth: no python

A Python package and CLI for parsing aggregate and forensic DMARC reports. Current version 9.10.3, requires Python >=3.10. Released regularly with new features and bug fixes.

pip install parsedmarc
error AttributeError: 'str' object has no attribute 'decode'
cause Python 3 compatibility: bytes.decode() used, but string passed.
fix
Ensure the input to parse_* functions is a string (not bytes). Use .decode() if reading from binary mode.
error ModuleNotFoundError: No module named 'parsedmarc.resources'
cause Missing resource package in installation; usually happens with older pip or incomplete install.
fix
Upgrade pip and reinstall: pip install --upgrade parsedmarc
error KeyError: 'email' in parsedmarc.resources.files
cause Internal resource reading error due to broken package, often after upgrading from very old version.
fix
Uninstall and reinstall: pip uninstall parsedmarc -y; pip install parsedmarc
error TypeError: '>' not supported between instances of 'str' and 'int'
cause Comparing version strings incorrectly; custom code sometimes passes wrong types.
fix
Use parsedmarc.__version__ (string) and parse with packaging.version.parse for comparisons.
breaking In version 8.0.0, the output format from parsedmarc changed from a list of dictionaries to a list of ParsedReport objects. Code relying on dictionary keys will break.
fix Access attributes via the ParsedReport object (e.g., report.policy_published) instead of dict keys.
breaking Support for Python 3.6 was dropped in version 7.0.0; Python 3.9 dropped in 9.0.0; Python 3.10 is required starting 9.0.0.
fix Use Python >=3.10. Update environment or use older parsedmarc version (<=8.x).
gotcha When using parsedmarc with Elasticsearch, the index mapping must be created manually or via the CLI '--es-index' flag. If not created, parsedmarc will not write to Elasticsearch and may fail silently.
fix Use the command-line option '--es-create-index' or set the environment variable PARSEDMARC_ES_CREATE_INDEX=true.
gotcha GeoIP lookups require the GeoIP2 database file (GeoLite2-City.mmdb). If not present and geoip2 is installed, parsing will fail with FileNotFoundError.
fix Set the environment variable PARSEDMARC_GEOIP_DB_PATH to the path of the MMDB file, or place the file in the default location.
deprecated The function parse_report_email() is deprecated in favor of parse_report() since version 7.0.0.
fix Use parse_report() instead. It accepts the same arguments.
pip install parsedmarc[elasticsearch,geoip2]

Minimal example to parse an aggregate DMARC XML report.

import os
from parsedmarc import parse_aggregate_report_xml

# Example: parse an aggregate DMARC report from a file
with open('aggregate_report.xml', 'r') as f:
    xml_data = f.read()

parsed = parse_aggregate_report_xml(xml_data)
print(parsed)

# If using IMAP, ensure credentials are set (optional)
os.environ.get('IMAP_HOST', 'imap.example.com')