Metadata-Version: 2.4
Name: fast-mail-parser-ng
Version: 0.6.0
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python
Classifier: Programming Language :: Rust
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Operating System :: POSIX
Classifier: Operating System :: Unix
Classifier: Topic :: Communications :: Email
Classifier: Topic :: Software Development :: Libraries
Requires-Dist: pytest~=7.4.4 ; extra == 'test'
Requires-Dist: pytest-benchmark==4.0.0 ; extra == 'test'
Requires-Dist: mail-parser==3.15.0 ; extra == 'test'
Provides-Extra: test
License-File: LICENSE
Summary: Very fast Python library for .eml files parsing.
Keywords: parser,email,rfc822,mime,maildir
Home-Page: https://github.com/namecheap/fast_mail_parser
Author-email: Andrii Sokyrko <wartwvister@gmail.com>
Maintainer: Namecheap
Requires-Python: >=3.11
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
Project-URL: Homepage, https://github.com/namecheap/fast_mail_parser
Project-URL: Issues, https://github.com/namecheap/fast_mail_parser/issues
Project-URL: Repository, https://github.com/namecheap/fast_mail_parser.git

# fast_mail_parser

![Test](https://github.com/namecheap/fast_mail_parser/workflows/Test/badge.svg)
[![PyPI version](https://badge.fury.io/py/fast-mail-parser-ng.svg)](https://badge.fury.io/py/fast-mail-parser-ng)
[![Downloads](https://pepy.tech/badge/fast-mail-parser-ng)](https://pepy.tech/project/fast-mail-parser-ng)

fast_mail_parser is a Python library for .eml files parsing.
The main benefit is a performance: the library is much faster than python implementations.

Based on [mailparse](https://github.com/staktrace/mailparse) library using [pyo3](https://github.com/PyO3/pyo3).

## Benchmark

```
 -------------------------------------------------------------------------------------------- benchmark: 2 tests -------------------------------------------------------------------------------------------
Name (time in ms)                              Min                Max               Mean            StdDev             Median               IQR            Outliers       OPS            Rounds  Iterations
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
test__fast_mail_parser___parse_message      1.8136 (1.0)       1.8938 (1.0)       1.8426 (1.0)      0.0176 (1.0)       1.8465 (1.0)      0.0277 (1.0)         180;0  542.7141 (1.0)         450           1
test__mail_parser___parse_message          14.5583 (8.03)     15.8571 (8.37)     15.0264 (8.16)     0.2368 (13.49)    14.9702 (8.11)     0.2887 (10.42)         5;1   66.5495 (0.12)         32           1
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Legend:
  Outliers: 1 Standard Deviation from Mean; 1.5 IQR (InterQuartile Range) from 1st Quartile and 3rd Quartile.
  OPS: Operations Per Second, computed as 1 / Mean
```

## Installation

Use the package manager [pip](https://pypi.org/project/fast-mail-parser-ng/) to install fast_mail_parser.

```bash
pip install fast-mail-parser-ng
```

> **Note on the package name.** The distribution is `fast-mail-parser-ng`, but
> the import path is plain `fast_mail_parser` — so only your requirements file
> changes, never your code.
>
> The `fast-mail-parser` name on PyPI is a different, unmaintained upload
> stuck at 0.2.5 (June 2022). It predates this repository's current
> maintenance and we cannot publish to it; see
> [CHANGELOG](CHANGELOG.md) for the full story. Install `fast-mail-parser-ng`
> to get the maintained library.

Wheels target the CPython stable ABI (`cp311-abi3`): one wheel per platform
covers every supported CPython version, including versions released after the
package — a new Python no longer has to wait for a new release.

| Python | Support |
| --- | --- |
| CPython 3.11+ (including future versions) | Prebuilt wheel |
| CPython 3.13t/3.14t (free-threaded) | Builds from source; the extension currently re-enables the GIL on import ([#101](https://github.com/namecheap/fast_mail_parser/issues/101)) |
| CPython ≤ 3.10 | Not supported (last compatible release: 0.2.5) |
| PyPy | Not supported |

## Usage

`parse_email` accepts the raw message as `str` or `bytes` and returns a
`PyMail`. It raises `ParseError` if the payload cannot be parsed.

`PyMail` exposes the following attributes:

| Attribute | Type | Description |
| --- | --- | --- |
| `subject` | `str` | Subject header (empty string if missing). |
| `date` | `str` | Date header (empty string if missing). |
| `text_plain` | `list[str]` | All `text/plain` bodies. |
| `text_html` | `list[str]` | All `text/html` bodies. |
| `headers` | `dict[str, str]` | All message headers. |
| `attachments` | `list[PyAttachment]` | Attachments (see below). |

Each `PyAttachment` has `mimetype: str`, `filename: str`, and `content: bytes`.

```python
import sys

from fast_mail_parser import parse_email, ParseError

# parse_email accepts both str and bytes; reading in binary mode is safest.
with open('message.eml', 'rb') as f:
    message_payload = f.read()

try:
    email = parse_email(message_payload)
except ParseError as e:
    print("Failed to parse email:", e)
    sys.exit(1)

print("Subject:", email.subject)
print("Date:", email.date)

# headers is a dict[str, str].
for name, value in email.headers.items():
    print(f"{name}: {value}")

# text_plain and text_html are lists of strings (one entry per matching part).
for body in email.text_plain:
    print("Plain text body:", body)

for body in email.text_html:
    print("HTML body:", body)

# attachments is a list of PyAttachment objects.
for attachment in email.attachments:
    print("Attachment:", attachment.filename)
    print("  mimetype:", attachment.mimetype)
    print("  size:", len(attachment.content), "bytes")  # content is bytes
```

## Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

Please make sure to update tests as appropriate.

See [CONTRIBUTING.md](CONTRIBUTING.md) for how to build from source, run the tests, and the PR conventions (linting, CI, DCO sign-off).

