Skip to content

Commit 67a0c3b

Browse files
committed
fix: address code review findings (docs part)
1 parent 6377ef9 commit 67a0c3b

5 files changed

Lines changed: 94 additions & 1 deletion

File tree

.github/workflows/tests.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ jobs:
7272
cache: pip
7373
- name: install dependencies
7474
run: |
75-
pip install -e .
75+
pip install -e ".[html]"
7676
pip install sphinx -r docs/requirements.txt
7777
- name: build docs
7878
run: sphinx-build -W -b html docs docs/_build/html

docs/api.rst

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,38 @@ Message Methods
8484
"user": "login", "password": "secret"}
8585
)
8686

87+
.. method:: Message.send_async(to=None, set_mail_to=True, mail_from=None, set_mail_from=False, render=None, smtp_mail_options=None, smtp_rcpt_options=None, smtp=None)
88+
89+
Send the message via SMTP asynchronously. Requires ``aiosmtplib``
90+
(install with ``pip install emails[async]``).
91+
92+
Parameters are the same as :meth:`send`, except ``smtp`` accepts a dict
93+
or an :class:`AsyncSMTPBackend` instance.
94+
95+
When ``smtp`` is a dict, a temporary :class:`AsyncSMTPBackend` is created
96+
and closed after sending. When an existing backend is passed, the caller
97+
is responsible for closing it.
98+
99+
:returns: :class:`SMTPResponse` or ``None``
100+
101+
Example::
102+
103+
response = await msg.send_async(
104+
to="user@example.com",
105+
smtp={"host": "smtp.example.com", "port": 587, "tls": True,
106+
"user": "login", "password": "secret"}
107+
)
108+
109+
Using a shared backend for multiple sends::
110+
111+
from emails.backend.smtp.aio_backend import AsyncSMTPBackend
112+
113+
async with AsyncSMTPBackend(host="smtp.example.com", port=587,
114+
tls=True, user="login",
115+
password="secret") as backend:
116+
for msg in messages:
117+
await msg.send_async(smtp=backend)
118+
87119
.. method:: Message.attach(\*\*kwargs)
88120

89121
Attach a file to the message. Sets ``content_disposition`` to ``'attachment'``
@@ -233,6 +265,12 @@ Message Properties
233265

234266
Get or set the template rendering context dictionary.
235267

268+
.. attribute:: Message.transformer
269+
270+
Access the HTML transformer for custom image/link transformations.
271+
Lazily created on first access. See the :doc:`HTML Transformations <transformations>`
272+
section for usage examples.
273+
236274

237275
SMTPResponse
238276
------------
@@ -281,6 +319,53 @@ Returned by :meth:`Message.send`. Contains information about the SMTP transactio
281319
print(f"Refused: {response.refused_recipients}")
282320

283321

322+
AsyncSMTPBackend
323+
----------------
324+
325+
For async sending via :meth:`Message.send_async`. Requires ``aiosmtplib``
326+
(install with ``pip install emails[async]``).
327+
328+
.. class:: emails.backend.smtp.aio_backend.AsyncSMTPBackend(ssl=False, fail_silently=True, mail_options=None, \*\*kwargs)
329+
330+
Manages an async SMTP connection. Supports ``async with`` for automatic cleanup.
331+
332+
:param host: SMTP server hostname.
333+
:param port: SMTP server port.
334+
:param ssl: Use implicit TLS (SMTPS).
335+
:param tls: Use STARTTLS after connecting.
336+
:param user: SMTP username for authentication.
337+
:param password: SMTP password for authentication.
338+
:param timeout: Connection timeout in seconds (default: ``5``).
339+
:param fail_silently: If ``True`` (default), SMTP errors are captured in the
340+
response rather than raised.
341+
:param mail_options: Default SMTP MAIL command options.
342+
343+
.. method:: sendmail(from_addr, to_addrs, msg, mail_options=None, rcpt_options=None)
344+
:async:
345+
346+
Send a message. Automatically retries once on server disconnect.
347+
348+
:returns: :class:`SMTPResponse` or ``None``
349+
350+
.. method:: close()
351+
:async:
352+
353+
Close the SMTP connection.
354+
355+
Example::
356+
357+
from emails.backend.smtp.aio_backend import AsyncSMTPBackend
358+
359+
async with AsyncSMTPBackend(host="smtp.example.com", port=587,
360+
tls=True, user="me",
361+
password="secret") as backend:
362+
response = await backend.sendmail(
363+
from_addr="sender@example.com",
364+
to_addrs=["recipient@example.com"],
365+
msg=message
366+
)
367+
368+
284369
Loaders
285370
-------
286371

docs/conf.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
'sphinx.ext.coverage',
1313
'sphinx.ext.ifconfig',
1414
'sphinx.ext.viewcode',
15+
'sphinx_togglebutton',
1516
]
1617

1718
templates_path = ['_templates']

docs/install.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,9 @@ To use Jinja2 templates (the ``T()`` shortcut):
2020
.. code-block:: bash
2121
2222
$ pip install emails[jinja]
23+
24+
To use async sending (``send_async()``):
25+
26+
.. code-block:: bash
27+
28+
$ pip install emails[async]

docs/requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
furo
2+
sphinx-togglebutton

0 commit comments

Comments
 (0)