Metadata-Version: 2.4
Name: epistole
Version: 0.0.6
Summary: Epistole is a single Python API for sending email, regardless of the backend.
Keywords: email,gmail,microsoft-graph,smtp
Author: Ozan Ozbeker
Author-email: Ozan Ozbeker <github@ozanozbeker.com>
License-Expression: MIT
License-File: LICENSE
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Communications :: Email
Classifier: Typing :: Typed
Requires-Dist: epistole[gmail,graph,markdown] ; extra == 'all'
Requires-Dist: google-auth>=2.57 ; extra == 'gmail'
Requires-Dist: httpx2>=2.12,<3 ; extra == 'gmail'
Requires-Dist: httpx2>=2.12,<3 ; extra == 'graph'
Requires-Dist: msal>=1.38 ; extra == 'graph'
Requires-Dist: markdown-it-py>=4.2 ; extra == 'markdown'
Requires-Python: >=3.13
Project-URL: Changelog, https://ozanozbeker.com/epistole/changelog.html
Project-URL: Documentation, https://ozanozbeker.com/epistole/
Project-URL: Issues, https://github.com/ozanozbeker/epistole/issues
Project-URL: Repository, https://github.com/ozanozbeker/epistole
Provides-Extra: all
Provides-Extra: gmail
Provides-Extra: graph
Provides-Extra: markdown
Description-Content-Type: text/markdown

# Epistole

Epistole takes a message you have already composed as HTML and sends it through whichever backend you have configured.
The interface is the same each time.
Supported backends are SMTP, Microsoft Graph, and Google.
The design allows more.
Switching providers means changing configuration, not rewriting your code.

This is an early project and the API is not yet stable.

> **Epistole** (ἐπιστολή, epistolē) is the Greek word for a letter or written message sent from one person to another.

## Install

```sh
uv add epistole
```

## Example

```python
from pathlib import Path
from epistole import Message, SMTPBackend, smtp

backend = SMTPBackend(
    host="mail.corp.example",
    port=587,
    from_address="reports@corp.example",
    credential=smtp.Password(username="reports", password=...),
)

backend.send(
    Message(html=Path("kpis.html").read_text(encoding="utf-8"))
    .subject("Daily KPIs")
    .to("boss@corp.example")
)
```

The backend opens a connection, authenticates, submits, and closes, all inside that one call.
With a wrong password, that line raises `AuthenticationError`.

The [user guide](https://ozanozbeker.com/epistole/user-guide/sending.html) walks through sending, writing HTML for email, choosing a backend and the tested mail services.
The [API reference](https://ozanozbeker.com/epistole/reference/) lists every public name.

## Credit

Epistole is inspired by [blastula](https://github.com/rstudio/blastula), an R package for composing and sending email.
It is not a port.
Its API does not copy blastula's.
