From 4b21fa687d1f0be3fb05227df27f4c3dde234cb0 Mon Sep 17 00:00:00 2001
From: Jules <54960783+juleswg23@users.noreply.github.com>
Date: Fri, 7 Nov 2025 10:49:33 -0500
Subject: [PATCH 1/4] rename to nbmail
---
.github/workflows/ci.yml | 14 +-
Makefile | 6 +-
README.md | 14 +-
docs/_quarto.yml | 4 +-
docs/objects.json | 2 +-
docs/summary.quarto_ipynb | 251 ++++++++++++++++++
examples/.gitignore | 2 +-
examples/emailer_lib.qmd | 0
{emailer_lib => nbmail}/__init__.py | 0
{emailer_lib => nbmail}/egress.py | 0
{emailer_lib => nbmail}/ingress.py | 0
{emailer_lib => nbmail}/mjml/.gitignore | 0
{emailer_lib => nbmail}/mjml/README.md | 14 +-
{emailer_lib => nbmail}/mjml/__init__.py | 0
{emailer_lib => nbmail}/mjml/_core.py | 0
.../mjml/image_processor.py | 4 +-
.../mjml/scripts/generate_tags.py | 6 +-
{emailer_lib => nbmail}/mjml/tags.py | 70 ++---
.../mjml/tests/test_core.py | 4 +-
.../mjml/tests/test_image_processor.py | 4 +-
.../mjml/tests/test_tags.py | 2 +-
{emailer_lib => nbmail}/structs.py | 0
.../tests/__snapshots__/test_structs.ambr | 0
{emailer_lib => nbmail}/tests/test_egress.py | 16 +-
.../tests/test_end_to_end.py | 6 +-
{emailer_lib => nbmail}/tests/test_ingress.py | 8 +-
{emailer_lib => nbmail}/tests/test_structs.py | 2 +-
{emailer_lib => nbmail}/tests/test_utils.py | 2 +-
{emailer_lib => nbmail}/utils.py | 0
pyproject.toml | 10 +-
uv.lock | 2 +-
31 files changed, 347 insertions(+), 96 deletions(-)
create mode 100644 docs/summary.quarto_ipynb
create mode 100644 examples/emailer_lib.qmd
rename {emailer_lib => nbmail}/__init__.py (100%)
rename {emailer_lib => nbmail}/egress.py (100%)
rename {emailer_lib => nbmail}/ingress.py (100%)
rename {emailer_lib => nbmail}/mjml/.gitignore (100%)
rename {emailer_lib => nbmail}/mjml/README.md (91%)
rename {emailer_lib => nbmail}/mjml/__init__.py (100%)
rename {emailer_lib => nbmail}/mjml/_core.py (100%)
rename {emailer_lib => nbmail}/mjml/image_processor.py (97%)
rename {emailer_lib => nbmail}/mjml/scripts/generate_tags.py (96%)
rename {emailer_lib => nbmail}/mjml/tags.py (94%)
rename {emailer_lib => nbmail}/mjml/tests/test_core.py (98%)
rename {emailer_lib => nbmail}/mjml/tests/test_image_processor.py (97%)
rename {emailer_lib => nbmail}/mjml/tests/test_tags.py (99%)
rename {emailer_lib => nbmail}/structs.py (100%)
rename {emailer_lib => nbmail}/tests/__snapshots__/test_structs.ambr (100%)
rename {emailer_lib => nbmail}/tests/test_egress.py (94%)
rename {emailer_lib => nbmail}/tests/test_end_to_end.py (93%)
rename {emailer_lib => nbmail}/tests/test_ingress.py (97%)
rename {emailer_lib => nbmail}/tests/test_structs.py (99%)
rename {emailer_lib => nbmail}/tests/test_utils.py (99%)
rename {emailer_lib => nbmail}/utils.py (100%)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 6115fc1..814cde2 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -30,7 +30,7 @@ jobs:
- name: Install the project
run: uv sync --all-extras --dev
- - name: Install emailer-lib
+ - name: Install nbmail
run: uv pip install -e .
# quarto docs build ----
@@ -57,7 +57,7 @@ jobs:
with:
source-dir: docs/_site
- test-emailer-lib:
+ test-nbmail:
runs-on: ubuntu-latest
strategy:
matrix:
@@ -80,19 +80,19 @@ jobs:
- name: Install the project
run: uv sync --all-extras --dev
- - name: Install emailer-lib
+ - name: Install nbmail
run: uv pip install -e .
- name: Install the project deps
run: uv pip install -e .[dev]
- - name: Test emailer-lib
+ - name: Test nbmail
run: |
- uv run pytest emailer_lib/tests/ --cov=emailer_lib --cov-report=xml --cov-report=term-missing
+ uv run pytest nbmail/tests/ --cov=nbmail --cov-report=xml --cov-report=term-missing
- name: Upload coverage reports
uses: codecov/codecov-action@v4
if: ${{ matrix.python-version == '3.12' }}
with:
- file: emailer-lib/coverage.xml
- flags: emailer-lib
+ file: nbmail/coverage.xml
+ flags: nbmail
diff --git a/Makefile b/Makefile
index c0c4950..b743416 100644
--- a/Makefile
+++ b/Makefile
@@ -5,10 +5,10 @@ preview:
cd docs && quarto preview
test:
- pytest emailer_lib/tests emailer_lib/mjml/tests --cov-report=xml
+ pytest nbmail/tests nbmail/mjml/tests --cov-report=xml
test-update:
- pytest emailer_lib/tests emailer_lib/mjml/tests --snapshot-update
+ pytest nbmail/tests nbmail/mjml/tests --snapshot-update
generate-mjml-tags:
- python3 emailer_lib/mjml/scripts/generate_tags.py
+ python3 nbmail/mjml/scripts/generate_tags.py
diff --git a/README.md b/README.md
index b026ae7..d4b19dc 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# emailer-lib
+# nbmail
@@ -11,12 +11,12 @@
-> ⚠️ **emailer-lib is currently in development, expect breaking changes.**
+> ⚠️ **nbmail is currently in development, expect breaking changes.**
-### What is [emailer-lib](https://posit-dev.github.io/email-for-data-science/reference/)?
+### What is [nbmail](https://posit-dev.github.io/email-for-data-science/reference/)?
-**emailer-lib** is a Python package for serializing, previewing, and sending email messages in a consistent, simple structure. It provides utilities to convert emails from different sources (Redmail, Yagmail, MJML, Quarto JSON) into a unified intermediate format, and send them via multiple backends (Gmail, SMTP, Mailgun, etc.).
+**nbmail** is a Python package for serializing, previewing, and sending email messages in a consistent, simple structure. It provides utilities to convert emails from different sources (Redmail, Yagmail, MJML, Quarto JSON) into a unified intermediate format, and send them via multiple backends (Gmail, SMTP, Mailgun, etc.).
The package is designed for data science workflows and Quarto projects, making it easy to generate, preview, and deliver rich email content programmatically.
@@ -24,14 +24,14 @@ The package is designed for data science workflows and Quarto projects, making i
Install the latest release from your local repo or PyPI:
```bash
-pip install -e ./emailer-lib
+pip install -e ./nbmail
```
-->
## Example Usage
```python
-from emailer_lib import (
+from nbmail import (
quarto_json_to_intermediate_email,
IntermediateEmail,
send_intermediate_email_with_gmail,
@@ -81,4 +81,4 @@ url = {https://github.com/posit-dev/gt-extras}, version = {0.0.1}
}
``` -->
-For more information, see the [docs](https://posit-dev.github.io/email-for-data-science/reference) or [open an issue](https://github.com/posit-dev/email-for-data-science/issues) with questions or suggestions!
\ No newline at end of file
+For more information, see the [docs](https://posit-dev.github.io/email-for-data-science/reference) or [open an issue](https://github.com/posit-dev/email-for-data-science/issues) with questions or suggestions!
diff --git a/docs/_quarto.yml b/docs/_quarto.yml
index cfa6598..78f67c8 100644
--- a/docs/_quarto.yml
+++ b/docs/_quarto.yml
@@ -29,7 +29,7 @@ website:
- orchestrating-tests.qmd
quartodoc:
- package: emailer_lib
+ package: nbmail
dir: reference
title: API Reference
css: reference/_styles-quartodoc.css
@@ -79,7 +79,7 @@ quartodoc:
- title: MJML Authoring
desc: >
Write responsive emails with MJML
- package: emailer_lib
+ package: nbmail
contents:
- mjml.mjml
- mjml.head
diff --git a/docs/objects.json b/docs/objects.json
index 6165209..fa4a566 100644
--- a/docs/objects.json
+++ b/docs/objects.json
@@ -1 +1 @@
-{"project": "emailer_lib", "version": "0.0.9999", "count": 106, "items": [{"name": "emailer_lib.IntermediateEmail.preview_send_email", "domain": "py", "role": "function", "priority": "1", "uri": "reference/emailer_lib.IntermediateEmail.preview_send_email.html#emailer_lib.IntermediateEmail.preview_send_email", "dispname": "-"}, {"name": "emailer_lib.structs.IntermediateEmail.preview_send_email", "domain": "py", "role": "function", "priority": "1", "uri": "reference/emailer_lib.IntermediateEmail.preview_send_email.html#emailer_lib.IntermediateEmail.preview_send_email", "dispname": "emailer_lib.IntermediateEmail.preview_send_email"}, {"name": "emailer_lib.IntermediateEmail.write_email_message", "domain": "py", "role": "function", "priority": "1", "uri": "reference/emailer_lib.IntermediateEmail.write_email_message.html#emailer_lib.IntermediateEmail.write_email_message", "dispname": "-"}, {"name": "emailer_lib.structs.IntermediateEmail.write_email_message", "domain": "py", "role": "function", "priority": "1", "uri": "reference/emailer_lib.IntermediateEmail.write_email_message.html#emailer_lib.IntermediateEmail.write_email_message", "dispname": "emailer_lib.IntermediateEmail.write_email_message"}, {"name": "emailer_lib.IntermediateEmail.write_preview_email", "domain": "py", "role": "function", "priority": "1", "uri": "reference/emailer_lib.IntermediateEmail.write_preview_email.html#emailer_lib.IntermediateEmail.write_preview_email", "dispname": "-"}, {"name": "emailer_lib.structs.IntermediateEmail.write_preview_email", "domain": "py", "role": "function", "priority": "1", "uri": "reference/emailer_lib.IntermediateEmail.write_preview_email.html#emailer_lib.IntermediateEmail.write_preview_email", "dispname": "emailer_lib.IntermediateEmail.write_preview_email"}, {"name": "emailer_lib.IntermediateEmail", "domain": "py", "role": "class", "priority": "1", "uri": "reference/IntermediateEmail.html#emailer_lib.IntermediateEmail", "dispname": "-"}, {"name": "emailer_lib.structs.IntermediateEmail", "domain": "py", "role": "class", "priority": "1", "uri": "reference/IntermediateEmail.html#emailer_lib.IntermediateEmail", "dispname": "emailer_lib.IntermediateEmail"}, {"name": "emailer_lib.IntermediateEmail.write_preview_email", "domain": "py", "role": "function", "priority": "1", "uri": "reference/IntermediateEmail.write_preview_email.html#emailer_lib.IntermediateEmail.write_preview_email", "dispname": "-"}, {"name": "emailer_lib.structs.IntermediateEmail.write_preview_email", "domain": "py", "role": "function", "priority": "1", "uri": "reference/IntermediateEmail.write_preview_email.html#emailer_lib.IntermediateEmail.write_preview_email", "dispname": "emailer_lib.IntermediateEmail.write_preview_email"}, {"name": "emailer_lib.IntermediateEmail.write_email_message", "domain": "py", "role": "function", "priority": "1", "uri": "reference/IntermediateEmail.write_email_message.html#emailer_lib.IntermediateEmail.write_email_message", "dispname": "-"}, {"name": "emailer_lib.structs.IntermediateEmail.write_email_message", "domain": "py", "role": "function", "priority": "1", "uri": "reference/IntermediateEmail.write_email_message.html#emailer_lib.IntermediateEmail.write_email_message", "dispname": "emailer_lib.IntermediateEmail.write_email_message"}, {"name": "emailer_lib.IntermediateEmail.preview_send_email", "domain": "py", "role": "function", "priority": "1", "uri": "reference/IntermediateEmail.preview_send_email.html#emailer_lib.IntermediateEmail.preview_send_email", "dispname": "-"}, {"name": "emailer_lib.structs.IntermediateEmail.preview_send_email", "domain": "py", "role": "function", "priority": "1", "uri": "reference/IntermediateEmail.preview_send_email.html#emailer_lib.IntermediateEmail.preview_send_email", "dispname": "emailer_lib.IntermediateEmail.preview_send_email"}, {"name": "emailer_lib.quarto_json_to_intermediate_email", "domain": "py", "role": "function", "priority": "1", "uri": "reference/quarto_json_to_intermediate_email.html#emailer_lib.quarto_json_to_intermediate_email", "dispname": "-"}, {"name": "emailer_lib.ingress.quarto_json_to_intermediate_email", "domain": "py", "role": "function", "priority": "1", "uri": "reference/quarto_json_to_intermediate_email.html#emailer_lib.quarto_json_to_intermediate_email", "dispname": "emailer_lib.quarto_json_to_intermediate_email"}, {"name": "emailer_lib.mjml_to_intermediate_email", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml_to_intermediate_email.html#emailer_lib.mjml_to_intermediate_email", "dispname": "-"}, {"name": "emailer_lib.ingress.mjml_to_intermediate_email", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml_to_intermediate_email.html#emailer_lib.mjml_to_intermediate_email", "dispname": "emailer_lib.mjml_to_intermediate_email"}, {"name": "emailer_lib.redmail_to_intermediate_email", "domain": "py", "role": "function", "priority": "1", "uri": "reference/redmail_to_intermediate_email.html#emailer_lib.redmail_to_intermediate_email", "dispname": "-"}, {"name": "emailer_lib.ingress.redmail_to_intermediate_email", "domain": "py", "role": "function", "priority": "1", "uri": "reference/redmail_to_intermediate_email.html#emailer_lib.redmail_to_intermediate_email", "dispname": "emailer_lib.redmail_to_intermediate_email"}, {"name": "emailer_lib.yagmail_to_intermediate_email", "domain": "py", "role": "function", "priority": "1", "uri": "reference/yagmail_to_intermediate_email.html#emailer_lib.yagmail_to_intermediate_email", "dispname": "-"}, {"name": "emailer_lib.ingress.yagmail_to_intermediate_email", "domain": "py", "role": "function", "priority": "1", "uri": "reference/yagmail_to_intermediate_email.html#emailer_lib.yagmail_to_intermediate_email", "dispname": "emailer_lib.yagmail_to_intermediate_email"}, {"name": "emailer_lib.send_intermediate_email_with_gmail", "domain": "py", "role": "function", "priority": "1", "uri": "reference/send_intermediate_email_with_gmail.html#emailer_lib.send_intermediate_email_with_gmail", "dispname": "-"}, {"name": "emailer_lib.egress.send_intermediate_email_with_gmail", "domain": "py", "role": "function", "priority": "1", "uri": "reference/send_intermediate_email_with_gmail.html#emailer_lib.send_intermediate_email_with_gmail", "dispname": "emailer_lib.send_intermediate_email_with_gmail"}, {"name": "emailer_lib.send_intermediate_email_with_smtp", "domain": "py", "role": "function", "priority": "1", "uri": "reference/send_intermediate_email_with_smtp.html#emailer_lib.send_intermediate_email_with_smtp", "dispname": "-"}, {"name": "emailer_lib.egress.send_intermediate_email_with_smtp", "domain": "py", "role": "function", "priority": "1", "uri": "reference/send_intermediate_email_with_smtp.html#emailer_lib.send_intermediate_email_with_smtp", "dispname": "emailer_lib.send_intermediate_email_with_smtp"}, {"name": "emailer_lib.send_intermediate_email_with_redmail", "domain": "py", "role": "function", "priority": "1", "uri": "reference/send_intermediate_email_with_redmail.html#emailer_lib.send_intermediate_email_with_redmail", "dispname": "-"}, {"name": "emailer_lib.egress.send_intermediate_email_with_redmail", "domain": "py", "role": "function", "priority": "1", "uri": "reference/send_intermediate_email_with_redmail.html#emailer_lib.send_intermediate_email_with_redmail", "dispname": "emailer_lib.send_intermediate_email_with_redmail"}, {"name": "emailer_lib.send_intermediate_email_with_yagmail", "domain": "py", "role": "function", "priority": "1", "uri": "reference/send_intermediate_email_with_yagmail.html#emailer_lib.send_intermediate_email_with_yagmail", "dispname": "-"}, {"name": "emailer_lib.egress.send_intermediate_email_with_yagmail", "domain": "py", "role": "function", "priority": "1", "uri": "reference/send_intermediate_email_with_yagmail.html#emailer_lib.send_intermediate_email_with_yagmail", "dispname": "emailer_lib.send_intermediate_email_with_yagmail"}, {"name": "emailer_lib.send_intermediate_email_with_mailgun", "domain": "py", "role": "function", "priority": "1", "uri": "reference/send_intermediate_email_with_mailgun.html#emailer_lib.send_intermediate_email_with_mailgun", "dispname": "-"}, {"name": "emailer_lib.egress.send_intermediate_email_with_mailgun", "domain": "py", "role": "function", "priority": "1", "uri": "reference/send_intermediate_email_with_mailgun.html#emailer_lib.send_intermediate_email_with_mailgun", "dispname": "emailer_lib.send_intermediate_email_with_mailgun"}, {"name": "emailer_lib.send_quarto_email_with_gmail", "domain": "py", "role": "function", "priority": "1", "uri": "reference/send_quarto_email_with_gmail.html#emailer_lib.send_quarto_email_with_gmail", "dispname": "-"}, {"name": "emailer_lib.egress.send_quarto_email_with_gmail", "domain": "py", "role": "function", "priority": "1", "uri": "reference/send_quarto_email_with_gmail.html#emailer_lib.send_quarto_email_with_gmail", "dispname": "emailer_lib.send_quarto_email_with_gmail"}, {"name": "emailer_lib.write_email_message_to_file", "domain": "py", "role": "function", "priority": "1", "uri": "reference/write_email_message_to_file.html#emailer_lib.write_email_message_to_file", "dispname": "-"}, {"name": "emailer_lib.utils.write_email_message_to_file", "domain": "py", "role": "function", "priority": "1", "uri": "reference/write_email_message_to_file.html#emailer_lib.write_email_message_to_file", "dispname": "emailer_lib.write_email_message_to_file"}, {"name": "emailer_lib.mjml.mjml", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.mjml.html#emailer_lib.mjml.mjml", "dispname": "-"}, {"name": "emailer_lib.mjml.tags.mjml", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.mjml.html#emailer_lib.mjml.mjml", "dispname": "emailer_lib.mjml.mjml"}, {"name": "emailer_lib.mjml.head", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.head.html#emailer_lib.mjml.head", "dispname": "-"}, {"name": "emailer_lib.mjml.tags.head", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.head.html#emailer_lib.mjml.head", "dispname": "emailer_lib.mjml.head"}, {"name": "emailer_lib.mjml.body", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.body.html#emailer_lib.mjml.body", "dispname": "-"}, {"name": "emailer_lib.mjml.tags.body", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.body.html#emailer_lib.mjml.body", "dispname": "emailer_lib.mjml.body"}, {"name": "emailer_lib.mjml.mj_attributes", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.mj_attributes.html#emailer_lib.mjml.mj_attributes", "dispname": "-"}, {"name": "emailer_lib.mjml.tags.mj_attributes", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.mj_attributes.html#emailer_lib.mjml.mj_attributes", "dispname": "emailer_lib.mjml.mj_attributes"}, {"name": "emailer_lib.mjml.mj_all", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.mj_all.html#emailer_lib.mjml.mj_all", "dispname": "-"}, {"name": "emailer_lib.mjml.tags.mj_all", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.mj_all.html#emailer_lib.mjml.mj_all", "dispname": "emailer_lib.mjml.mj_all"}, {"name": "emailer_lib.mjml.mj_class", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.mj_class.html#emailer_lib.mjml.mj_class", "dispname": "-"}, {"name": "emailer_lib.mjml.tags.mj_class", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.mj_class.html#emailer_lib.mjml.mj_class", "dispname": "emailer_lib.mjml.mj_class"}, {"name": "emailer_lib.mjml.breakpoint", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.breakpoint.html#emailer_lib.mjml.breakpoint", "dispname": "-"}, {"name": "emailer_lib.mjml.tags.breakpoint", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.breakpoint.html#emailer_lib.mjml.breakpoint", "dispname": "emailer_lib.mjml.breakpoint"}, {"name": "emailer_lib.mjml.font", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.font.html#emailer_lib.mjml.font", "dispname": "-"}, {"name": "emailer_lib.mjml.tags.font", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.font.html#emailer_lib.mjml.font", "dispname": "emailer_lib.mjml.font"}, {"name": "emailer_lib.mjml.html_attributes", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.html_attributes.html#emailer_lib.mjml.html_attributes", "dispname": "-"}, {"name": "emailer_lib.mjml.tags.html_attributes", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.html_attributes.html#emailer_lib.mjml.html_attributes", "dispname": "emailer_lib.mjml.html_attributes"}, {"name": "emailer_lib.mjml.html_attribute", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.html_attribute.html#emailer_lib.mjml.html_attribute", "dispname": "-"}, {"name": "emailer_lib.mjml.tags.html_attribute", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.html_attribute.html#emailer_lib.mjml.html_attribute", "dispname": "emailer_lib.mjml.html_attribute"}, {"name": "emailer_lib.mjml.preview", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.preview.html#emailer_lib.mjml.preview", "dispname": "-"}, {"name": "emailer_lib.mjml.tags.preview", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.preview.html#emailer_lib.mjml.preview", "dispname": "emailer_lib.mjml.preview"}, {"name": "emailer_lib.mjml.style", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.style.html#emailer_lib.mjml.style", "dispname": "-"}, {"name": "emailer_lib.mjml.tags.style", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.style.html#emailer_lib.mjml.style", "dispname": "emailer_lib.mjml.style"}, {"name": "emailer_lib.mjml.title", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.title.html#emailer_lib.mjml.title", "dispname": "-"}, {"name": "emailer_lib.mjml.tags.title", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.title.html#emailer_lib.mjml.title", "dispname": "emailer_lib.mjml.title"}, {"name": "emailer_lib.mjml.accordion", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.accordion.html#emailer_lib.mjml.accordion", "dispname": "-"}, {"name": "emailer_lib.mjml.tags.accordion", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.accordion.html#emailer_lib.mjml.accordion", "dispname": "emailer_lib.mjml.accordion"}, {"name": "emailer_lib.mjml.accordion_element", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.accordion_element.html#emailer_lib.mjml.accordion_element", "dispname": "-"}, {"name": "emailer_lib.mjml.tags.accordion_element", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.accordion_element.html#emailer_lib.mjml.accordion_element", "dispname": "emailer_lib.mjml.accordion_element"}, {"name": "emailer_lib.mjml.accordion_text", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.accordion_text.html#emailer_lib.mjml.accordion_text", "dispname": "-"}, {"name": "emailer_lib.mjml.tags.accordion_text", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.accordion_text.html#emailer_lib.mjml.accordion_text", "dispname": "emailer_lib.mjml.accordion_text"}, {"name": "emailer_lib.mjml.accordion_title", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.accordion_title.html#emailer_lib.mjml.accordion_title", "dispname": "-"}, {"name": "emailer_lib.mjml.tags.accordion_title", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.accordion_title.html#emailer_lib.mjml.accordion_title", "dispname": "emailer_lib.mjml.accordion_title"}, {"name": "emailer_lib.mjml.button", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.button.html#emailer_lib.mjml.button", "dispname": "-"}, {"name": "emailer_lib.mjml.tags.button", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.button.html#emailer_lib.mjml.button", "dispname": "emailer_lib.mjml.button"}, {"name": "emailer_lib.mjml.carousel", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.carousel.html#emailer_lib.mjml.carousel", "dispname": "-"}, {"name": "emailer_lib.mjml.tags.carousel", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.carousel.html#emailer_lib.mjml.carousel", "dispname": "emailer_lib.mjml.carousel"}, {"name": "emailer_lib.mjml.carousel_image", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.carousel_image.html#emailer_lib.mjml.carousel_image", "dispname": "-"}, {"name": "emailer_lib.mjml.tags.carousel_image", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.carousel_image.html#emailer_lib.mjml.carousel_image", "dispname": "emailer_lib.mjml.carousel_image"}, {"name": "emailer_lib.mjml.column", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.column.html#emailer_lib.mjml.column", "dispname": "-"}, {"name": "emailer_lib.mjml.tags.column", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.column.html#emailer_lib.mjml.column", "dispname": "emailer_lib.mjml.column"}, {"name": "emailer_lib.mjml.divider", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.divider.html#emailer_lib.mjml.divider", "dispname": "-"}, {"name": "emailer_lib.mjml.tags.divider", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.divider.html#emailer_lib.mjml.divider", "dispname": "emailer_lib.mjml.divider"}, {"name": "emailer_lib.mjml.group", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.group.html#emailer_lib.mjml.group", "dispname": "-"}, {"name": "emailer_lib.mjml.tags.group", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.group.html#emailer_lib.mjml.group", "dispname": "emailer_lib.mjml.group"}, {"name": "emailer_lib.mjml.hero", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.hero.html#emailer_lib.mjml.hero", "dispname": "-"}, {"name": "emailer_lib.mjml.tags.hero", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.hero.html#emailer_lib.mjml.hero", "dispname": "emailer_lib.mjml.hero"}, {"name": "emailer_lib.mjml.image", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.image.html#emailer_lib.mjml.image", "dispname": "-"}, {"name": "emailer_lib.mjml.tags.image", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.image.html#emailer_lib.mjml.image", "dispname": "emailer_lib.mjml.image"}, {"name": "emailer_lib.mjml.navbar", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.navbar.html#emailer_lib.mjml.navbar", "dispname": "-"}, {"name": "emailer_lib.mjml.tags.navbar", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.navbar.html#emailer_lib.mjml.navbar", "dispname": "emailer_lib.mjml.navbar"}, {"name": "emailer_lib.mjml.navbar_link", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.navbar_link.html#emailer_lib.mjml.navbar_link", "dispname": "-"}, {"name": "emailer_lib.mjml.tags.navbar_link", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.navbar_link.html#emailer_lib.mjml.navbar_link", "dispname": "emailer_lib.mjml.navbar_link"}, {"name": "emailer_lib.mjml.raw", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.raw.html#emailer_lib.mjml.raw", "dispname": "-"}, {"name": "emailer_lib.mjml.tags.raw", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.raw.html#emailer_lib.mjml.raw", "dispname": "emailer_lib.mjml.raw"}, {"name": "emailer_lib.mjml.section", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.section.html#emailer_lib.mjml.section", "dispname": "-"}, {"name": "emailer_lib.mjml.tags.section", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.section.html#emailer_lib.mjml.section", "dispname": "emailer_lib.mjml.section"}, {"name": "emailer_lib.mjml.social", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.social.html#emailer_lib.mjml.social", "dispname": "-"}, {"name": "emailer_lib.mjml.tags.social", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.social.html#emailer_lib.mjml.social", "dispname": "emailer_lib.mjml.social"}, {"name": "emailer_lib.mjml.social_element", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.social_element.html#emailer_lib.mjml.social_element", "dispname": "-"}, {"name": "emailer_lib.mjml.tags.social_element", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.social_element.html#emailer_lib.mjml.social_element", "dispname": "emailer_lib.mjml.social_element"}, {"name": "emailer_lib.mjml.spacer", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.spacer.html#emailer_lib.mjml.spacer", "dispname": "-"}, {"name": "emailer_lib.mjml.tags.spacer", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.spacer.html#emailer_lib.mjml.spacer", "dispname": "emailer_lib.mjml.spacer"}, {"name": "emailer_lib.mjml.table", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.table.html#emailer_lib.mjml.table", "dispname": "-"}, {"name": "emailer_lib.mjml.tags.table", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.table.html#emailer_lib.mjml.table", "dispname": "emailer_lib.mjml.table"}, {"name": "emailer_lib.mjml.text", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.text.html#emailer_lib.mjml.text", "dispname": "-"}, {"name": "emailer_lib.mjml.tags.text", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.text.html#emailer_lib.mjml.text", "dispname": "emailer_lib.mjml.text"}, {"name": "emailer_lib.mjml.wrapper", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.wrapper.html#emailer_lib.mjml.wrapper", "dispname": "-"}, {"name": "emailer_lib.mjml.tags.wrapper", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.wrapper.html#emailer_lib.mjml.wrapper", "dispname": "emailer_lib.mjml.wrapper"}]}
\ No newline at end of file
+{"project": "nbmail", "version": "0.0.9999", "count": 106, "items": [{"name": "nbmail.IntermediateEmail.preview_send_email", "domain": "py", "role": "function", "priority": "1", "uri": "reference/nbmail.IntermediateEmail.preview_send_email.html#nbmail.IntermediateEmail.preview_send_email", "dispname": "-"}, {"name": "nbmail.structs.IntermediateEmail.preview_send_email", "domain": "py", "role": "function", "priority": "1", "uri": "reference/nbmail.IntermediateEmail.preview_send_email.html#nbmail.IntermediateEmail.preview_send_email", "dispname": "nbmail.IntermediateEmail.preview_send_email"}, {"name": "nbmail.IntermediateEmail.write_email_message", "domain": "py", "role": "function", "priority": "1", "uri": "reference/nbmail.IntermediateEmail.write_email_message.html#nbmail.IntermediateEmail.write_email_message", "dispname": "-"}, {"name": "nbmail.structs.IntermediateEmail.write_email_message", "domain": "py", "role": "function", "priority": "1", "uri": "reference/nbmail.IntermediateEmail.write_email_message.html#nbmail.IntermediateEmail.write_email_message", "dispname": "nbmail.IntermediateEmail.write_email_message"}, {"name": "nbmail.IntermediateEmail.write_preview_email", "domain": "py", "role": "function", "priority": "1", "uri": "reference/nbmail.IntermediateEmail.write_preview_email.html#nbmail.IntermediateEmail.write_preview_email", "dispname": "-"}, {"name": "nbmail.structs.IntermediateEmail.write_preview_email", "domain": "py", "role": "function", "priority": "1", "uri": "reference/nbmail.IntermediateEmail.write_preview_email.html#nbmail.IntermediateEmail.write_preview_email", "dispname": "nbmail.IntermediateEmail.write_preview_email"}, {"name": "nbmail.IntermediateEmail", "domain": "py", "role": "class", "priority": "1", "uri": "reference/IntermediateEmail.html#nbmail.IntermediateEmail", "dispname": "-"}, {"name": "nbmail.structs.IntermediateEmail", "domain": "py", "role": "class", "priority": "1", "uri": "reference/IntermediateEmail.html#nbmail.IntermediateEmail", "dispname": "nbmail.IntermediateEmail"}, {"name": "nbmail.IntermediateEmail.write_preview_email", "domain": "py", "role": "function", "priority": "1", "uri": "reference/IntermediateEmail.write_preview_email.html#nbmail.IntermediateEmail.write_preview_email", "dispname": "-"}, {"name": "nbmail.structs.IntermediateEmail.write_preview_email", "domain": "py", "role": "function", "priority": "1", "uri": "reference/IntermediateEmail.write_preview_email.html#nbmail.IntermediateEmail.write_preview_email", "dispname": "nbmail.IntermediateEmail.write_preview_email"}, {"name": "nbmail.IntermediateEmail.write_email_message", "domain": "py", "role": "function", "priority": "1", "uri": "reference/IntermediateEmail.write_email_message.html#nbmail.IntermediateEmail.write_email_message", "dispname": "-"}, {"name": "nbmail.structs.IntermediateEmail.write_email_message", "domain": "py", "role": "function", "priority": "1", "uri": "reference/IntermediateEmail.write_email_message.html#nbmail.IntermediateEmail.write_email_message", "dispname": "nbmail.IntermediateEmail.write_email_message"}, {"name": "nbmail.IntermediateEmail.preview_send_email", "domain": "py", "role": "function", "priority": "1", "uri": "reference/IntermediateEmail.preview_send_email.html#nbmail.IntermediateEmail.preview_send_email", "dispname": "-"}, {"name": "nbmail.structs.IntermediateEmail.preview_send_email", "domain": "py", "role": "function", "priority": "1", "uri": "reference/IntermediateEmail.preview_send_email.html#nbmail.IntermediateEmail.preview_send_email", "dispname": "nbmail.IntermediateEmail.preview_send_email"}, {"name": "nbmail.quarto_json_to_intermediate_email", "domain": "py", "role": "function", "priority": "1", "uri": "reference/quarto_json_to_intermediate_email.html#nbmail.quarto_json_to_intermediate_email", "dispname": "-"}, {"name": "nbmail.ingress.quarto_json_to_intermediate_email", "domain": "py", "role": "function", "priority": "1", "uri": "reference/quarto_json_to_intermediate_email.html#nbmail.quarto_json_to_intermediate_email", "dispname": "nbmail.quarto_json_to_intermediate_email"}, {"name": "nbmail.mjml_to_intermediate_email", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml_to_intermediate_email.html#nbmail.mjml_to_intermediate_email", "dispname": "-"}, {"name": "nbmail.ingress.mjml_to_intermediate_email", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml_to_intermediate_email.html#nbmail.mjml_to_intermediate_email", "dispname": "nbmail.mjml_to_intermediate_email"}, {"name": "nbmail.redmail_to_intermediate_email", "domain": "py", "role": "function", "priority": "1", "uri": "reference/redmail_to_intermediate_email.html#nbmail.redmail_to_intermediate_email", "dispname": "-"}, {"name": "nbmail.ingress.redmail_to_intermediate_email", "domain": "py", "role": "function", "priority": "1", "uri": "reference/redmail_to_intermediate_email.html#nbmail.redmail_to_intermediate_email", "dispname": "nbmail.redmail_to_intermediate_email"}, {"name": "nbmail.yagmail_to_intermediate_email", "domain": "py", "role": "function", "priority": "1", "uri": "reference/yagmail_to_intermediate_email.html#nbmail.yagmail_to_intermediate_email", "dispname": "-"}, {"name": "nbmail.ingress.yagmail_to_intermediate_email", "domain": "py", "role": "function", "priority": "1", "uri": "reference/yagmail_to_intermediate_email.html#nbmail.yagmail_to_intermediate_email", "dispname": "nbmail.yagmail_to_intermediate_email"}, {"name": "nbmail.send_intermediate_email_with_gmail", "domain": "py", "role": "function", "priority": "1", "uri": "reference/send_intermediate_email_with_gmail.html#nbmail.send_intermediate_email_with_gmail", "dispname": "-"}, {"name": "nbmail.egress.send_intermediate_email_with_gmail", "domain": "py", "role": "function", "priority": "1", "uri": "reference/send_intermediate_email_with_gmail.html#nbmail.send_intermediate_email_with_gmail", "dispname": "nbmail.send_intermediate_email_with_gmail"}, {"name": "nbmail.send_intermediate_email_with_smtp", "domain": "py", "role": "function", "priority": "1", "uri": "reference/send_intermediate_email_with_smtp.html#nbmail.send_intermediate_email_with_smtp", "dispname": "-"}, {"name": "nbmail.egress.send_intermediate_email_with_smtp", "domain": "py", "role": "function", "priority": "1", "uri": "reference/send_intermediate_email_with_smtp.html#nbmail.send_intermediate_email_with_smtp", "dispname": "nbmail.send_intermediate_email_with_smtp"}, {"name": "nbmail.send_intermediate_email_with_redmail", "domain": "py", "role": "function", "priority": "1", "uri": "reference/send_intermediate_email_with_redmail.html#nbmail.send_intermediate_email_with_redmail", "dispname": "-"}, {"name": "nbmail.egress.send_intermediate_email_with_redmail", "domain": "py", "role": "function", "priority": "1", "uri": "reference/send_intermediate_email_with_redmail.html#nbmail.send_intermediate_email_with_redmail", "dispname": "nbmail.send_intermediate_email_with_redmail"}, {"name": "nbmail.send_intermediate_email_with_yagmail", "domain": "py", "role": "function", "priority": "1", "uri": "reference/send_intermediate_email_with_yagmail.html#nbmail.send_intermediate_email_with_yagmail", "dispname": "-"}, {"name": "nbmail.egress.send_intermediate_email_with_yagmail", "domain": "py", "role": "function", "priority": "1", "uri": "reference/send_intermediate_email_with_yagmail.html#nbmail.send_intermediate_email_with_yagmail", "dispname": "nbmail.send_intermediate_email_with_yagmail"}, {"name": "nbmail.send_intermediate_email_with_mailgun", "domain": "py", "role": "function", "priority": "1", "uri": "reference/send_intermediate_email_with_mailgun.html#nbmail.send_intermediate_email_with_mailgun", "dispname": "-"}, {"name": "nbmail.egress.send_intermediate_email_with_mailgun", "domain": "py", "role": "function", "priority": "1", "uri": "reference/send_intermediate_email_with_mailgun.html#nbmail.send_intermediate_email_with_mailgun", "dispname": "nbmail.send_intermediate_email_with_mailgun"}, {"name": "nbmail.send_quarto_email_with_gmail", "domain": "py", "role": "function", "priority": "1", "uri": "reference/send_quarto_email_with_gmail.html#nbmail.send_quarto_email_with_gmail", "dispname": "-"}, {"name": "nbmail.egress.send_quarto_email_with_gmail", "domain": "py", "role": "function", "priority": "1", "uri": "reference/send_quarto_email_with_gmail.html#nbmail.send_quarto_email_with_gmail", "dispname": "nbmail.send_quarto_email_with_gmail"}, {"name": "nbmail.write_email_message_to_file", "domain": "py", "role": "function", "priority": "1", "uri": "reference/write_email_message_to_file.html#nbmail.write_email_message_to_file", "dispname": "-"}, {"name": "nbmail.utils.write_email_message_to_file", "domain": "py", "role": "function", "priority": "1", "uri": "reference/write_email_message_to_file.html#nbmail.write_email_message_to_file", "dispname": "nbmail.write_email_message_to_file"}, {"name": "nbmail.mjml.mjml", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.mjml.html#nbmail.mjml.mjml", "dispname": "-"}, {"name": "nbmail.mjml.tags.mjml", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.mjml.html#nbmail.mjml.mjml", "dispname": "nbmail.mjml.mjml"}, {"name": "nbmail.mjml.head", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.head.html#nbmail.mjml.head", "dispname": "-"}, {"name": "nbmail.mjml.tags.head", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.head.html#nbmail.mjml.head", "dispname": "nbmail.mjml.head"}, {"name": "nbmail.mjml.body", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.body.html#nbmail.mjml.body", "dispname": "-"}, {"name": "nbmail.mjml.tags.body", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.body.html#nbmail.mjml.body", "dispname": "nbmail.mjml.body"}, {"name": "nbmail.mjml.mj_attributes", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.mj_attributes.html#nbmail.mjml.mj_attributes", "dispname": "-"}, {"name": "nbmail.mjml.tags.mj_attributes", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.mj_attributes.html#nbmail.mjml.mj_attributes", "dispname": "nbmail.mjml.mj_attributes"}, {"name": "nbmail.mjml.mj_all", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.mj_all.html#nbmail.mjml.mj_all", "dispname": "-"}, {"name": "nbmail.mjml.tags.mj_all", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.mj_all.html#nbmail.mjml.mj_all", "dispname": "nbmail.mjml.mj_all"}, {"name": "nbmail.mjml.mj_class", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.mj_class.html#nbmail.mjml.mj_class", "dispname": "-"}, {"name": "nbmail.mjml.tags.mj_class", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.mj_class.html#nbmail.mjml.mj_class", "dispname": "nbmail.mjml.mj_class"}, {"name": "nbmail.mjml.breakpoint", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.breakpoint.html#nbmail.mjml.breakpoint", "dispname": "-"}, {"name": "nbmail.mjml.tags.breakpoint", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.breakpoint.html#nbmail.mjml.breakpoint", "dispname": "nbmail.mjml.breakpoint"}, {"name": "nbmail.mjml.font", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.font.html#nbmail.mjml.font", "dispname": "-"}, {"name": "nbmail.mjml.tags.font", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.font.html#nbmail.mjml.font", "dispname": "nbmail.mjml.font"}, {"name": "nbmail.mjml.html_attributes", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.html_attributes.html#nbmail.mjml.html_attributes", "dispname": "-"}, {"name": "nbmail.mjml.tags.html_attributes", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.html_attributes.html#nbmail.mjml.html_attributes", "dispname": "nbmail.mjml.html_attributes"}, {"name": "nbmail.mjml.html_attribute", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.html_attribute.html#nbmail.mjml.html_attribute", "dispname": "-"}, {"name": "nbmail.mjml.tags.html_attribute", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.html_attribute.html#nbmail.mjml.html_attribute", "dispname": "nbmail.mjml.html_attribute"}, {"name": "nbmail.mjml.preview", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.preview.html#nbmail.mjml.preview", "dispname": "-"}, {"name": "nbmail.mjml.tags.preview", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.preview.html#nbmail.mjml.preview", "dispname": "nbmail.mjml.preview"}, {"name": "nbmail.mjml.style", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.style.html#nbmail.mjml.style", "dispname": "-"}, {"name": "nbmail.mjml.tags.style", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.style.html#nbmail.mjml.style", "dispname": "nbmail.mjml.style"}, {"name": "nbmail.mjml.title", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.title.html#nbmail.mjml.title", "dispname": "-"}, {"name": "nbmail.mjml.tags.title", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.title.html#nbmail.mjml.title", "dispname": "nbmail.mjml.title"}, {"name": "nbmail.mjml.accordion", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.accordion.html#nbmail.mjml.accordion", "dispname": "-"}, {"name": "nbmail.mjml.tags.accordion", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.accordion.html#nbmail.mjml.accordion", "dispname": "nbmail.mjml.accordion"}, {"name": "nbmail.mjml.accordion_element", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.accordion_element.html#nbmail.mjml.accordion_element", "dispname": "-"}, {"name": "nbmail.mjml.tags.accordion_element", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.accordion_element.html#nbmail.mjml.accordion_element", "dispname": "nbmail.mjml.accordion_element"}, {"name": "nbmail.mjml.accordion_text", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.accordion_text.html#nbmail.mjml.accordion_text", "dispname": "-"}, {"name": "nbmail.mjml.tags.accordion_text", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.accordion_text.html#nbmail.mjml.accordion_text", "dispname": "nbmail.mjml.accordion_text"}, {"name": "nbmail.mjml.accordion_title", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.accordion_title.html#nbmail.mjml.accordion_title", "dispname": "-"}, {"name": "nbmail.mjml.tags.accordion_title", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.accordion_title.html#nbmail.mjml.accordion_title", "dispname": "nbmail.mjml.accordion_title"}, {"name": "nbmail.mjml.button", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.button.html#nbmail.mjml.button", "dispname": "-"}, {"name": "nbmail.mjml.tags.button", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.button.html#nbmail.mjml.button", "dispname": "nbmail.mjml.button"}, {"name": "nbmail.mjml.carousel", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.carousel.html#nbmail.mjml.carousel", "dispname": "-"}, {"name": "nbmail.mjml.tags.carousel", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.carousel.html#nbmail.mjml.carousel", "dispname": "nbmail.mjml.carousel"}, {"name": "nbmail.mjml.carousel_image", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.carousel_image.html#nbmail.mjml.carousel_image", "dispname": "-"}, {"name": "nbmail.mjml.tags.carousel_image", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.carousel_image.html#nbmail.mjml.carousel_image", "dispname": "nbmail.mjml.carousel_image"}, {"name": "nbmail.mjml.column", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.column.html#nbmail.mjml.column", "dispname": "-"}, {"name": "nbmail.mjml.tags.column", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.column.html#nbmail.mjml.column", "dispname": "nbmail.mjml.column"}, {"name": "nbmail.mjml.divider", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.divider.html#nbmail.mjml.divider", "dispname": "-"}, {"name": "nbmail.mjml.tags.divider", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.divider.html#nbmail.mjml.divider", "dispname": "nbmail.mjml.divider"}, {"name": "nbmail.mjml.group", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.group.html#nbmail.mjml.group", "dispname": "-"}, {"name": "nbmail.mjml.tags.group", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.group.html#nbmail.mjml.group", "dispname": "nbmail.mjml.group"}, {"name": "nbmail.mjml.hero", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.hero.html#nbmail.mjml.hero", "dispname": "-"}, {"name": "nbmail.mjml.tags.hero", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.hero.html#nbmail.mjml.hero", "dispname": "nbmail.mjml.hero"}, {"name": "nbmail.mjml.image", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.image.html#nbmail.mjml.image", "dispname": "-"}, {"name": "nbmail.mjml.tags.image", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.image.html#nbmail.mjml.image", "dispname": "nbmail.mjml.image"}, {"name": "nbmail.mjml.navbar", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.navbar.html#nbmail.mjml.navbar", "dispname": "-"}, {"name": "nbmail.mjml.tags.navbar", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.navbar.html#nbmail.mjml.navbar", "dispname": "nbmail.mjml.navbar"}, {"name": "nbmail.mjml.navbar_link", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.navbar_link.html#nbmail.mjml.navbar_link", "dispname": "-"}, {"name": "nbmail.mjml.tags.navbar_link", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.navbar_link.html#nbmail.mjml.navbar_link", "dispname": "nbmail.mjml.navbar_link"}, {"name": "nbmail.mjml.raw", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.raw.html#nbmail.mjml.raw", "dispname": "-"}, {"name": "nbmail.mjml.tags.raw", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.raw.html#nbmail.mjml.raw", "dispname": "nbmail.mjml.raw"}, {"name": "nbmail.mjml.section", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.section.html#nbmail.mjml.section", "dispname": "-"}, {"name": "nbmail.mjml.tags.section", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.section.html#nbmail.mjml.section", "dispname": "nbmail.mjml.section"}, {"name": "nbmail.mjml.social", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.social.html#nbmail.mjml.social", "dispname": "-"}, {"name": "nbmail.mjml.tags.social", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.social.html#nbmail.mjml.social", "dispname": "nbmail.mjml.social"}, {"name": "nbmail.mjml.social_element", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.social_element.html#nbmail.mjml.social_element", "dispname": "-"}, {"name": "nbmail.mjml.tags.social_element", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.social_element.html#nbmail.mjml.social_element", "dispname": "nbmail.mjml.social_element"}, {"name": "nbmail.mjml.spacer", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.spacer.html#nbmail.mjml.spacer", "dispname": "-"}, {"name": "nbmail.mjml.tags.spacer", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.spacer.html#nbmail.mjml.spacer", "dispname": "nbmail.mjml.spacer"}, {"name": "nbmail.mjml.table", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.table.html#nbmail.mjml.table", "dispname": "-"}, {"name": "nbmail.mjml.tags.table", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.table.html#nbmail.mjml.table", "dispname": "nbmail.mjml.table"}, {"name": "nbmail.mjml.text", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.text.html#nbmail.mjml.text", "dispname": "-"}, {"name": "nbmail.mjml.tags.text", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.text.html#nbmail.mjml.text", "dispname": "nbmail.mjml.text"}, {"name": "nbmail.mjml.wrapper", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.wrapper.html#nbmail.mjml.wrapper", "dispname": "-"}, {"name": "nbmail.mjml.tags.wrapper", "domain": "py", "role": "function", "priority": "1", "uri": "reference/mjml.wrapper.html#nbmail.mjml.wrapper", "dispname": "nbmail.mjml.wrapper"}]}
diff --git a/docs/summary.quarto_ipynb b/docs/summary.quarto_ipynb
new file mode 100644
index 0000000..31b113c
--- /dev/null
+++ b/docs/summary.quarto_ipynb
@@ -0,0 +1,251 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# The whole game\n",
+ "\n",
+ "\n",
+ "\n",
+ "Emailing reports is a critical but challenging task for data science.\n",
+ "Mainly because you have to figure out generating the email content, configuring pieces like attachments, and orchestrating it (e.g. testing, or sending on a schedule). Moreover, content can range from simple layouts to more complex ones.\n",
+ "\n",
+ "In this tutorial, we'll walk through the whole game of sending email. We'll start with this simple example:\n"
+ ],
+ "id": "14101fd1"
+ },
+ {
+ "cell_type": "code",
+ "metadata": {},
+ "source": [
+ "# | code-fold: true\n",
+ "# | eval: false\n",
+ "import os\n",
+ "from dotenv import load_dotenv\n",
+ "from data_polars import sp500\n",
+ "import redmail\n",
+ "\n",
+ "load_dotenv()\n",
+ "gmail_address = os.environ[\"GMAIL_ADDRESS\"]\n",
+ "gmail_app_password = os.environ[\"GMAIL_APP_PASSWORD\"]\n",
+ "\n",
+ "\n",
+ "email_subject = \"Report on Cars\"\n",
+ "email_body = sp500.head(10).style.as_raw_html(inline_css=True)\n",
+ "\n",
+ "# This is here to emphasize the sender does not have to be the same as the receiver\n",
+ "email_receiver = gmail_address\n",
+ "\n",
+ "redmail.gmail.username = gmail_address\n",
+ "redmail.gmail.password = gmail_app_password\n",
+ "\n",
+ "redmail.gmail.send(\n",
+ " subject=email_subject,\n",
+ " receivers=[email_receiver],\n",
+ " html=email_body,\n",
+ ")"
+ ],
+ "id": "3e29c5ba",
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "{width=50% fig-align=\"center\"}\n",
+ "\n",
+ "* **Content**: writing the text of the email, including plots and tables.\n",
+ "* **Composing**: setting up the subject, sender, and receivers.\n",
+ "* **Orchestrating**: previewing, testing, and scheduling the email.\n",
+ "\n",
+ "We'll also quickly review writing more advanced content layouts, and authoring email reports that involve running code with Quarto.\n",
+ "\n",
+ "## A simple email\n",
+ "\n",
+ "{width=50% fig-align=\"center\"}\n",
+ "\n",
+ "* Generate and preview\n",
+ "* Authenticate (may need to refer to its own authentication page in guide)\n",
+ "* Send\n"
+ ],
+ "id": "31ca0b47"
+ },
+ {
+ "cell_type": "code",
+ "metadata": {},
+ "source": [
+ "# | code-fold: true\n",
+ "# | eval: false\n",
+ "import os\n",
+ "from dotenv import load_dotenv\n",
+ "from data_polars import sp500\n",
+ "import redmail\n",
+ "\n",
+ "load_dotenv()\n",
+ "gmail_address = os.environ[\"GMAIL_ADDRESS\"]\n",
+ "gmail_app_password = os.environ[\"GMAIL_APP_PASSWORD\"]\n",
+ "\n",
+ "\n",
+ "email_subject = \"Report on Cars\"\n",
+ "email_body = sp500.head(10).style.as_raw_html(inline_css=True)\n",
+ "\n",
+ "# This is here to emphasize the sender does not have to be the same as the receiver\n",
+ "email_receiver = gmail_address\n",
+ "\n",
+ "redmail.gmail.username = gmail_address\n",
+ "redmail.gmail.password = gmail_app_password\n",
+ "\n",
+ "redmail.gmail.send(\n",
+ " subject=email_subject,\n",
+ " receivers=[email_receiver],\n",
+ " html=email_body,\n",
+ ")"
+ ],
+ "id": "ecc38edf",
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Configure: subject, recipients, attachments\n",
+ "\n",
+ "* you could attach the data as a CSV attachment\n",
+ "\n",
+ "\n",
+ "## Orchestrate: save and preview\n",
+ "\n",
+ "* previewing email\n",
+ "* intermediate json, easy for sending email later\n",
+ "* embedding images makes previewing hard\n",
+ "* can always email to yourself (or use a test service like Litmus)\n",
+ "\n",
+ "## Content: Quarto authoring\n",
+ "\n",
+ "Here's our same simple email generated using quarto.\n",
+ "\n",
+ "\n",
+ "\n",
+ "{width=50% fig-align=\"center\"}\n",
+ "\n",
+ "* Focused on basic configuring, and content\n",
+ "* Sending happens via our tool\n",
+ "* Generate using quarto render\n",
+ "* Can preview email\n",
+ "\n",
+ "## Content: advanced layouts\n",
+ "\n",
+ "We'll highlight the key pieces (discussed later in this guide) to go from that simple email, to a more advanced on like below:\n",
+ "\n",
+ "{width=50% fig-align=\"center\"}\n",
+ "\n",
+ "\n",
+ "## Fridge\n",
+ "\n",
+ "In this tutorial, we are going to send an email from a Gmail account. To do so, you will need to [create an App Password](https://support.google.com/accounts/answer/185833). Note this is only possible if you've [enabled 2-step verification](https://support.google.com/accounts/answer/185839).\n",
+ "\n",
+ "\n",
+ "\n",
+ "::: {.callout-tip}\n",
+ "This is just one of many options: it is also possible to send emails in Python from other email providers (Outlook, ProtonMail, etc.), or even from a custom domain. To skip ahead to a discussion of alternative sending methods, see [Authentication](orchestrating-auth.qmd)\n",
+ ":::\n",
+ "\n",
+ "Once you've created your App Password, that is used as your Gmail password for sending with Python. \n",
+ "\n",
+ "There are many ways to store the password seperate from your email-sending code, so as to not expose any sensitive information. One such approach uses a `.env` file, and the ``dotenv` and `os` packages.\n",
+ "\n",
+ "```{.sh filename=\".env\"}\n",
+ "GMAIL_APP_PASSWORD=abcd abcd abcd abcd\n",
+ "```\n",
+ "\n",
+ "```{.python filename=\"main.py\"}\n",
+ "import os\n",
+ "from dotenv import load_dotenv\n",
+ "\n",
+ "load_dotenv()\n",
+ "\n",
+ "your_gmail_address = \"YourGmail@gmail.com\"\n",
+ "gmail_app_password = os.environ[\"GMAIL_APP_PASSWORD\"]\n",
+ "```\n",
+ "\n",
+ "Check out the email content we will send.\n"
+ ],
+ "id": "840912f2"
+ },
+ {
+ "cell_type": "code",
+ "metadata": {},
+ "source": [
+ "from data_polars import sp500\n",
+ "\n",
+ "sp500.head(10).style"
+ ],
+ "id": "0cda1fb2",
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "And now we send the email!\n"
+ ],
+ "id": "f44aff8c"
+ },
+ {
+ "cell_type": "code",
+ "metadata": {},
+ "source": [
+ "# | eval: false\n",
+ "import redmail\n",
+ "\n",
+ "redmail.gmail.username = your_gmail_address\n",
+ "redmail.gmail.password = gmail_app_password\n",
+ "\n",
+ "redmail.gmail.send(\n",
+ " subject=\"An Example Email\",\n",
+ " receivers=[username],\n",
+ " html=email_html,\n",
+ " text=email_plaintext,\n",
+ ")"
+ ],
+ "id": "4ad22022",
+ "execution_count": null,
+ "outputs": []
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ ""
+ ],
+ "id": "15ee0056"
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "name": "python3",
+ "language": "python",
+ "display_name": "Python 3 (ipykernel)",
+ "path": "/Users/jules-wg/Library/Python/3.9/share/jupyter/kernels/python3"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
\ No newline at end of file
diff --git a/examples/.gitignore b/examples/.gitignore
index bd2bfd4..a131850 100644
--- a/examples/.gitignore
+++ b/examples/.gitignore
@@ -1,2 +1,2 @@
playground.qmd
-emailer_lib.qmd
\ No newline at end of file
+nbmail.qmd
diff --git a/examples/emailer_lib.qmd b/examples/emailer_lib.qmd
new file mode 100644
index 0000000..e69de29
diff --git a/emailer_lib/__init__.py b/nbmail/__init__.py
similarity index 100%
rename from emailer_lib/__init__.py
rename to nbmail/__init__.py
diff --git a/emailer_lib/egress.py b/nbmail/egress.py
similarity index 100%
rename from emailer_lib/egress.py
rename to nbmail/egress.py
diff --git a/emailer_lib/ingress.py b/nbmail/ingress.py
similarity index 100%
rename from emailer_lib/ingress.py
rename to nbmail/ingress.py
diff --git a/emailer_lib/mjml/.gitignore b/nbmail/mjml/.gitignore
similarity index 100%
rename from emailer_lib/mjml/.gitignore
rename to nbmail/mjml/.gitignore
diff --git a/emailer_lib/mjml/README.md b/nbmail/mjml/README.md
similarity index 91%
rename from emailer_lib/mjml/README.md
rename to nbmail/mjml/README.md
index 16efad3..2b3c624 100644
--- a/emailer_lib/mjml/README.md
+++ b/nbmail/mjml/README.md
@@ -14,16 +14,16 @@ This module provides Python functions for creating MJML markup, the responsive e
## Installation
-This module is part of the `emailer_lib` package:
+This module is part of the `nbmail` package:
```python
-from emailer_lib import mjml as mj
+from nbmail import mjml as mj
```
## Quick Start
```python
-from emailer_lib.mjml import mjml, body, section, column, text
+from nbmail.mjml import mjml, body, section, column, text
# Build an MJML email structure
email = mjml(
@@ -99,7 +99,7 @@ button(
The base class for all MJML elements. Can be instantiated directly or via helper functions.
```python
-from emailer_lib.mjml import MJMLTag
+from nbmail.mjml import MJMLTag
tag = MJMLTag(
"mj-text",
@@ -117,7 +117,7 @@ A dictionary type for tag attributes.
### Simple Email
```python
-from emailer_lib.mjml import mjml, head, body, section, column, text, title
+from nbmail.mjml import mjml, head, body, section, column, text, title
email = mjml(
head(
@@ -136,7 +136,7 @@ email = mjml(
### Multi-column Layout
```python
-from emailer_lib.mjml import body, section, column, text, image
+from nbmail.mjml import body, section, column, text, image
layout = body(
section(
@@ -157,7 +157,7 @@ layout = body(
### Using Attributes
```python
-from emailer_lib.mjml import section, column, text
+from nbmail.mjml import section, column, text
# Attributes as kwargs
section(
diff --git a/emailer_lib/mjml/__init__.py b/nbmail/mjml/__init__.py
similarity index 100%
rename from emailer_lib/mjml/__init__.py
rename to nbmail/mjml/__init__.py
diff --git a/emailer_lib/mjml/_core.py b/nbmail/mjml/_core.py
similarity index 100%
rename from emailer_lib/mjml/_core.py
rename to nbmail/mjml/_core.py
diff --git a/emailer_lib/mjml/image_processor.py b/nbmail/mjml/image_processor.py
similarity index 97%
rename from emailer_lib/mjml/image_processor.py
rename to nbmail/mjml/image_processor.py
index 02c61ed..4395686 100644
--- a/emailer_lib/mjml/image_processor.py
+++ b/nbmail/mjml/image_processor.py
@@ -73,8 +73,8 @@ def _process_mjml_images(mjml_tag: MJMLTag) -> Tuple[MJMLTag, Dict[str, str]]:
Examples
--------
```python
- from emailer_lib.mjml import mjml, body, section, column, image
- from emailer_lib import mjml_to_intermediate_email
+ from nbmail.mjml import mjml, body, section, column, image
+ from nbmail import mjml_to_intermediate_email
from io import BytesIO
# Create BytesIO with image data
diff --git a/emailer_lib/mjml/scripts/generate_tags.py b/nbmail/mjml/scripts/generate_tags.py
similarity index 96%
rename from emailer_lib/mjml/scripts/generate_tags.py
rename to nbmail/mjml/scripts/generate_tags.py
index d84b7f0..86fae9a 100644
--- a/emailer_lib/mjml/scripts/generate_tags.py
+++ b/nbmail/mjml/scripts/generate_tags.py
@@ -115,7 +115,7 @@ def {py_name}(
--------
With children:
```{{python}}
- from emailer_lib.mjml import {py_name}, text
+ from nbmail.mjml import {py_name}, text
child = text("Hello World")
result = {py_name}(child)
@@ -165,7 +165,7 @@ def {py_name}(
--------
With content:
```{{python}}
- from emailer_lib.mjml import {py_name}
+ from nbmail.mjml import {py_name}
result = {py_name}("Hello")
```
@@ -182,7 +182,7 @@ def {py_name}(
# Combine all parts
output = header + "\n".join(functions)
- # Write to file - navigate from scripts/ to emailer_lib/mjml/tags.py
+ # Write to file - navigate from scripts/ to nbmail/mjml/tags.py
script_dir = Path(__file__).parent
tags_file = script_dir.parent / "tags.py"
diff --git a/emailer_lib/mjml/tags.py b/nbmail/mjml/tags.py
similarity index 94%
rename from emailer_lib/mjml/tags.py
rename to nbmail/mjml/tags.py
index 1cdbf1c..3589fc7 100644
--- a/emailer_lib/mjml/tags.py
+++ b/nbmail/mjml/tags.py
@@ -35,7 +35,7 @@ def mjml(
--------
With children:
```{python}
- from emailer_lib.mjml import mjml, text
+ from nbmail.mjml import mjml, text
child = text("Hello World")
result = mjml(child)
@@ -80,7 +80,7 @@ def head(
--------
With children:
```{python}
- from emailer_lib.mjml import head, text
+ from nbmail.mjml import head, text
child = text("Hello World")
result = head(child)
@@ -125,7 +125,7 @@ def body(
--------
With children:
```{python}
- from emailer_lib.mjml import body, text
+ from nbmail.mjml import body, text
child = text("Hello World")
result = body(child)
@@ -170,7 +170,7 @@ def mj_attributes(
--------
With children:
```{python}
- from emailer_lib.mjml import mj_attributes, text
+ from nbmail.mjml import mj_attributes, text
child = text("Hello World")
result = mj_attributes(child)
@@ -215,7 +215,7 @@ def mj_all(
--------
With children:
```{python}
- from emailer_lib.mjml import mj_all, text
+ from nbmail.mjml import mj_all, text
child = text("Hello World")
result = mj_all(child)
@@ -260,7 +260,7 @@ def mj_class(
--------
With children:
```{python}
- from emailer_lib.mjml import mj_class, text
+ from nbmail.mjml import mj_class, text
child = text("Hello World")
result = mj_class(child)
@@ -305,7 +305,7 @@ def breakpoint(
--------
With children:
```{python}
- from emailer_lib.mjml import breakpoint, text
+ from nbmail.mjml import breakpoint, text
child = text("Hello World")
result = breakpoint(child)
@@ -350,7 +350,7 @@ def font(
--------
With children:
```{python}
- from emailer_lib.mjml import font, text
+ from nbmail.mjml import font, text
child = text("Hello World")
result = font(child)
@@ -395,7 +395,7 @@ def html_attributes(
--------
With children:
```{python}
- from emailer_lib.mjml import html_attributes, text
+ from nbmail.mjml import html_attributes, text
child = text("Hello World")
result = html_attributes(child)
@@ -440,7 +440,7 @@ def html_attribute(
--------
With children:
```{python}
- from emailer_lib.mjml import html_attribute, text
+ from nbmail.mjml import html_attribute, text
child = text("Hello World")
result = html_attribute(child)
@@ -485,7 +485,7 @@ def preview(
--------
With children:
```{python}
- from emailer_lib.mjml import preview, text
+ from nbmail.mjml import preview, text
child = text("Hello World")
result = preview(child)
@@ -530,7 +530,7 @@ def style(
--------
With children:
```{python}
- from emailer_lib.mjml import style, text
+ from nbmail.mjml import style, text
child = text("Hello World")
result = style(child)
@@ -575,7 +575,7 @@ def accordion(
--------
With children:
```{python}
- from emailer_lib.mjml import accordion, text
+ from nbmail.mjml import accordion, text
child = text("Hello World")
result = accordion(child)
@@ -620,7 +620,7 @@ def accordion_element(
--------
With children:
```{python}
- from emailer_lib.mjml import accordion_element, text
+ from nbmail.mjml import accordion_element, text
child = text("Hello World")
result = accordion_element(child)
@@ -665,7 +665,7 @@ def carousel(
--------
With children:
```{python}
- from emailer_lib.mjml import carousel, text
+ from nbmail.mjml import carousel, text
child = text("Hello World")
result = carousel(child)
@@ -710,7 +710,7 @@ def column(
--------
With children:
```{python}
- from emailer_lib.mjml import column, text
+ from nbmail.mjml import column, text
child = text("Hello World")
result = column(child)
@@ -755,7 +755,7 @@ def divider(
--------
With children:
```{python}
- from emailer_lib.mjml import divider, text
+ from nbmail.mjml import divider, text
child = text("Hello World")
result = divider(child)
@@ -800,7 +800,7 @@ def group(
--------
With children:
```{python}
- from emailer_lib.mjml import group, text
+ from nbmail.mjml import group, text
child = text("Hello World")
result = group(child)
@@ -845,7 +845,7 @@ def hero(
--------
With children:
```{python}
- from emailer_lib.mjml import hero, text
+ from nbmail.mjml import hero, text
child = text("Hello World")
result = hero(child)
@@ -890,7 +890,7 @@ def image(
--------
With children:
```{python}
- from emailer_lib.mjml import image, text
+ from nbmail.mjml import image, text
child = text("Hello World")
result = image(child)
@@ -935,7 +935,7 @@ def navbar(
--------
With children:
```{python}
- from emailer_lib.mjml import navbar, text
+ from nbmail.mjml import navbar, text
child = text("Hello World")
result = navbar(child)
@@ -980,7 +980,7 @@ def section(
--------
With children:
```{python}
- from emailer_lib.mjml import section, text
+ from nbmail.mjml import section, text
child = text("Hello World")
result = section(child)
@@ -1025,7 +1025,7 @@ def social(
--------
With children:
```{python}
- from emailer_lib.mjml import social, text
+ from nbmail.mjml import social, text
child = text("Hello World")
result = social(child)
@@ -1070,7 +1070,7 @@ def spacer(
--------
With children:
```{python}
- from emailer_lib.mjml import spacer, text
+ from nbmail.mjml import spacer, text
child = text("Hello World")
result = spacer(child)
@@ -1115,7 +1115,7 @@ def wrapper(
--------
With children:
```{python}
- from emailer_lib.mjml import wrapper, text
+ from nbmail.mjml import wrapper, text
child = text("Hello World")
result = wrapper(child)
@@ -1159,7 +1159,7 @@ def accordion_text(
--------
With content:
```{python}
- from emailer_lib.mjml import accordion_text
+ from nbmail.mjml import accordion_text
result = accordion_text("Hello")
```
@@ -1197,7 +1197,7 @@ def accordion_title(
--------
With content:
```{python}
- from emailer_lib.mjml import accordion_title
+ from nbmail.mjml import accordion_title
result = accordion_title("Hello")
```
@@ -1235,7 +1235,7 @@ def button(
--------
With content:
```{python}
- from emailer_lib.mjml import button
+ from nbmail.mjml import button
result = button("Hello")
```
@@ -1273,7 +1273,7 @@ def carousel_image(
--------
With content:
```{python}
- from emailer_lib.mjml import carousel_image
+ from nbmail.mjml import carousel_image
result = carousel_image("Hello")
```
@@ -1311,7 +1311,7 @@ def navbar_link(
--------
With content:
```{python}
- from emailer_lib.mjml import navbar_link
+ from nbmail.mjml import navbar_link
result = navbar_link("Hello")
```
@@ -1349,7 +1349,7 @@ def raw(
--------
With content:
```{python}
- from emailer_lib.mjml import raw
+ from nbmail.mjml import raw
result = raw("Hello")
```
@@ -1387,7 +1387,7 @@ def social_element(
--------
With content:
```{python}
- from emailer_lib.mjml import social_element
+ from nbmail.mjml import social_element
result = social_element("Hello")
```
@@ -1425,7 +1425,7 @@ def table(
--------
With content:
```{python}
- from emailer_lib.mjml import table
+ from nbmail.mjml import table
result = table("Hello")
```
@@ -1463,7 +1463,7 @@ def text(
--------
With content:
```{python}
- from emailer_lib.mjml import text
+ from nbmail.mjml import text
result = text("Hello")
```
@@ -1501,7 +1501,7 @@ def title(
--------
With content:
```{python}
- from emailer_lib.mjml import title
+ from nbmail.mjml import title
result = title("Hello")
```
diff --git a/emailer_lib/mjml/tests/test_core.py b/nbmail/mjml/tests/test_core.py
similarity index 98%
rename from emailer_lib/mjml/tests/test_core.py
rename to nbmail/mjml/tests/test_core.py
index 6069c15..05bcffd 100644
--- a/emailer_lib/mjml/tests/test_core.py
+++ b/nbmail/mjml/tests/test_core.py
@@ -1,7 +1,7 @@
import pytest
from io import BytesIO
-from emailer_lib.ingress import mjml_to_intermediate_email
-from emailer_lib.mjml._core import MJMLTag, TagAttrDict
+from nbmail.ingress import mjml_to_intermediate_email
+from nbmail.mjml._core import MJMLTag, TagAttrDict
def test_accepts_dict_arguments():
diff --git a/emailer_lib/mjml/tests/test_image_processor.py b/nbmail/mjml/tests/test_image_processor.py
similarity index 97%
rename from emailer_lib/mjml/tests/test_image_processor.py
rename to nbmail/mjml/tests/test_image_processor.py
index 5fe2f5c..ecd5d97 100644
--- a/emailer_lib/mjml/tests/test_image_processor.py
+++ b/nbmail/mjml/tests/test_image_processor.py
@@ -1,8 +1,8 @@
import pytest
from io import BytesIO
-from emailer_lib.mjml.image_processor import _convert_to_bytes, _process_mjml_images
-from emailer_lib.mjml._core import MJMLTag
+from nbmail.mjml.image_processor import _convert_to_bytes, _process_mjml_images
+from nbmail.mjml._core import MJMLTag
def test_convert_to_bytes_from_bytesio():
diff --git a/emailer_lib/mjml/tests/test_tags.py b/nbmail/mjml/tests/test_tags.py
similarity index 99%
rename from emailer_lib/mjml/tests/test_tags.py
rename to nbmail/mjml/tests/test_tags.py
index 3ea9305..0b4f5d0 100644
--- a/emailer_lib/mjml/tests/test_tags.py
+++ b/nbmail/mjml/tests/test_tags.py
@@ -1,5 +1,5 @@
import pytest
-from emailer_lib.mjml import (
+from nbmail.mjml import (
MJMLTag,
mjml,
head,
diff --git a/emailer_lib/structs.py b/nbmail/structs.py
similarity index 100%
rename from emailer_lib/structs.py
rename to nbmail/structs.py
diff --git a/emailer_lib/tests/__snapshots__/test_structs.ambr b/nbmail/tests/__snapshots__/test_structs.ambr
similarity index 100%
rename from emailer_lib/tests/__snapshots__/test_structs.ambr
rename to nbmail/tests/__snapshots__/test_structs.ambr
diff --git a/emailer_lib/tests/test_egress.py b/nbmail/tests/test_egress.py
similarity index 94%
rename from emailer_lib/tests/test_egress.py
rename to nbmail/tests/test_egress.py
index e8abc65..26200af 100644
--- a/emailer_lib/tests/test_egress.py
+++ b/nbmail/tests/test_egress.py
@@ -2,7 +2,7 @@
import pytest
-from emailer_lib.egress import (
+from nbmail.egress import (
send_intermediate_email_with_redmail,
send_intermediate_email_with_yagmail,
send_intermediate_email_with_mailgun,
@@ -10,7 +10,7 @@
send_intermediate_email_with_gmail,
send_quarto_email_with_gmail,
)
-from emailer_lib.structs import IntermediateEmail
+from nbmail.structs import IntermediateEmail
def make_basic_email():
@@ -31,9 +31,9 @@ def setup_smtp_mocks(monkeypatch):
context = mock_smtp.return_value.__enter__.return_value
- # Patch in the emailer_lib.egress module where they're used
- monkeypatch.setattr("emailer_lib.egress.smtplib.SMTP", mock_smtp)
- monkeypatch.setattr("emailer_lib.egress.smtplib.SMTP_SSL", mock_smtp_ssl)
+ # Patch in the nbmail.egress module where they're used
+ monkeypatch.setattr("nbmail.egress.smtplib.SMTP", mock_smtp)
+ monkeypatch.setattr("nbmail.egress.smtplib.SMTP_SSL", mock_smtp_ssl)
return mock_smtp, mock_smtp_ssl, context
@@ -43,7 +43,7 @@ def test_send_intermediate_email_with_gmail_calls_smtp(monkeypatch):
mock_smtp_send = MagicMock()
monkeypatch.setattr(
- "emailer_lib.egress.send_intermediate_email_with_smtp", mock_smtp_send
+ "nbmail.egress.send_intermediate_email_with_smtp", mock_smtp_send
)
send_intermediate_email_with_gmail("user@gmail.com", "pass", email)
@@ -178,13 +178,13 @@ def test_send_quarto_email_with_gmail(monkeypatch):
# Mock the quarto_json_to_intermediate_email function
mock_quarto_to_email = MagicMock(return_value=make_basic_email())
monkeypatch.setattr(
- "emailer_lib.egress.quarto_json_to_intermediate_email", mock_quarto_to_email
+ "nbmail.egress.quarto_json_to_intermediate_email", mock_quarto_to_email
)
# Mock the Gmail sending function
mock_send_gmail = MagicMock()
monkeypatch.setattr(
- "emailer_lib.egress.send_intermediate_email_with_gmail", mock_send_gmail
+ "nbmail.egress.send_intermediate_email_with_gmail", mock_send_gmail
)
# Call the function
diff --git a/emailer_lib/tests/test_end_to_end.py b/nbmail/tests/test_end_to_end.py
similarity index 93%
rename from emailer_lib/tests/test_end_to_end.py
rename to nbmail/tests/test_end_to_end.py
index 7c01906..42f62fc 100644
--- a/emailer_lib/tests/test_end_to_end.py
+++ b/nbmail/tests/test_end_to_end.py
@@ -2,8 +2,8 @@
import time
from aiosmtpd.controller import Controller
from email import message_from_bytes
-from emailer_lib.egress import send_intermediate_email_with_smtp
-from emailer_lib.structs import IntermediateEmail
+from nbmail.egress import send_intermediate_email_with_smtp
+from nbmail.structs import IntermediateEmail
class EmailHandler:
@@ -87,4 +87,4 @@ def test_send_email_integration(smtp_server):
inline_images = [p for p in msg.walk() if p.get('Content-ID')]
assert len(inline_images) == 1
- assert ' Hello world Hello world Hello world
Hello 
Hi
", subject="Test", recipients=["a@example.com"], @@ -38,15 +38,15 @@ def setup_smtp_mocks(monkeypatch): return mock_smtp, mock_smtp_ssl, context -def test_send_intermediate_email_with_gmail_calls_smtp(monkeypatch): +def test_send_email_with_gmail_calls_smtp(monkeypatch): email = make_basic_email() mock_smtp_send = MagicMock() monkeypatch.setattr( - "nbmail.egress.send_intermediate_email_with_smtp", mock_smtp_send + "nbmail.egress.send_email_with_smtp", mock_smtp_send ) - send_intermediate_email_with_gmail("user@gmail.com", "pass", email) + send_email_with_gmail("user@gmail.com", "pass", email) mock_smtp_send.assert_called_once_with( smtp_host="smtp.gmail.com", @@ -58,11 +58,11 @@ def test_send_intermediate_email_with_gmail_calls_smtp(monkeypatch): ) -def test_send_intermediate_email_with_smtp_tls(monkeypatch): +def test_send_email_with_smtp_tls(monkeypatch): email = make_basic_email() mock_smtp, mock_smtp_ssl, context = setup_smtp_mocks(monkeypatch) - send_intermediate_email_with_smtp( + send_email_with_smtp( smtp_host="smtp.example.com", smtp_port=587, username="user", @@ -77,11 +77,11 @@ def test_send_intermediate_email_with_smtp_tls(monkeypatch): context.sendmail.assert_called_once() -def test_send_intermediate_email_with_smtp_ssl(monkeypatch): +def test_send_email_with_smtp_ssl(monkeypatch): email = make_basic_email() mock_smtp, mock_smtp_ssl, context = setup_smtp_mocks(monkeypatch) - send_intermediate_email_with_smtp( + send_email_with_smtp( smtp_host="smtp.example.com", smtp_port=465, username="user", @@ -95,14 +95,14 @@ def test_send_intermediate_email_with_smtp_ssl(monkeypatch): context.sendmail.assert_called_once() -def test_send_intermediate_email_with_smtp_with_attachment(monkeypatch): +def test_send_email_with_smtp_with_attachment(monkeypatch): email = make_basic_email() email.external_attachments = ["file.txt"] mock_smtp, mock_smtp_ssl, context = setup_smtp_mocks(monkeypatch) with patch("builtins.open", mock_open(read_data=b"data")): - send_intermediate_email_with_smtp( + send_email_with_smtp( smtp_host="smtp.example.com", smtp_port=587, username="user", @@ -117,14 +117,14 @@ def test_send_intermediate_email_with_smtp_with_attachment(monkeypatch): assert 'Content-Disposition: attachment; filename="file.txt"' in email_message -def test_send_intermediate_email_with_smtp_unknown_mime_type(monkeypatch): +def test_send_email_with_smtp_unknown_mime_type(monkeypatch): email = make_basic_email() email.external_attachments = ["file_without_extension"] mock_smtp, mock_smtp_ssl, context = setup_smtp_mocks(monkeypatch) with patch("builtins.open", mock_open(read_data=b"data")): - send_intermediate_email_with_smtp( + send_email_with_smtp( smtp_host="smtp.example.com", smtp_port=587, username="user", @@ -144,11 +144,11 @@ def test_send_intermediate_email_with_smtp_unknown_mime_type(monkeypatch): ) -def test_send_intermediate_email_with_smtp_sendmail_args(monkeypatch): +def test_send_email_with_smtp_sendmail_args(monkeypatch): email = make_basic_email() mock_smtp, mock_smtp_ssl, context = setup_smtp_mocks(monkeypatch) - send_intermediate_email_with_smtp( + send_email_with_smtp( smtp_host="mock_host", smtp_port=465, username="user@gmail.com", @@ -175,16 +175,16 @@ def test_send_intermediate_email_with_smtp_sendmail_args(monkeypatch): # this is probably not the best way to test this, # for what it's worth I will test each part separately def test_send_quarto_email_with_gmail(monkeypatch): - # Mock the quarto_json_to_intermediate_email function + # Mock the quarto_json_to_email function mock_quarto_to_email = MagicMock(return_value=make_basic_email()) monkeypatch.setattr( - "nbmail.egress.quarto_json_to_intermediate_email", mock_quarto_to_email + "nbmail.egress.quarto_json_to_email", mock_quarto_to_email ) # Mock the Gmail sending function mock_send_gmail = MagicMock() monkeypatch.setattr( - "nbmail.egress.send_intermediate_email_with_gmail", mock_send_gmail + "nbmail.egress.send_email_with_gmail", mock_send_gmail ) # Call the function @@ -203,7 +203,7 @@ def test_send_quarto_email_with_gmail(monkeypatch): assert i_email.recipients == ["recipient@example.com"] -def test_send_intermediate_email_with_mailgun(monkeypatch): +def test_send_email_with_mailgun(monkeypatch): email = make_basic_email() email.external_attachments = ["file.txt"] @@ -225,7 +225,7 @@ def test_send_intermediate_email_with_mailgun(monkeypatch): with patch("mailgun.client.Client", mock_client_class): with patch("builtins.open", mock_open(read_data=b"file content")): - response = send_intermediate_email_with_mailgun( + response = send_email_with_mailgun( api_key="test-api-key", domain="mg.example.com", sender="sender@example.com", @@ -259,15 +259,15 @@ def test_send_intermediate_email_with_mailgun(monkeypatch): } -def test_send_intermediate_email_with_mailgun_no_recipients(): - email = IntermediateEmail( +def test_send_email_with_mailgun_no_recipients(): + email = Email( html="Hi
", subject="Test", recipients=None, ) with pytest.raises(TypeError, match="i_email must have a populated recipients attribute"): - send_intermediate_email_with_mailgun( + send_email_with_mailgun( api_key="test-api-key", domain="mg.example.com", sender="sender@example.com", @@ -278,8 +278,8 @@ def test_send_intermediate_email_with_mailgun_no_recipients(): @pytest.mark.parametrize( "send_func", [ - send_intermediate_email_with_redmail, - send_intermediate_email_with_yagmail, + send_email_with_redmail, + send_email_with_yagmail, ], ) def test_not_implemented_functions(send_func): diff --git a/nbmail/tests/test_end_to_end.py b/nbmail/tests/test_end_to_end.py index 42f62fc..29a6175 100644 --- a/nbmail/tests/test_end_to_end.py +++ b/nbmail/tests/test_end_to_end.py @@ -2,8 +2,8 @@ import time from aiosmtpd.controller import Controller from email import message_from_bytes -from nbmail.egress import send_intermediate_email_with_smtp -from nbmail.structs import IntermediateEmail +from nbmail.egress import send_email_with_smtp +from nbmail.structs import Email class EmailHandler: @@ -37,7 +37,7 @@ def smtp_server(): def test_send_email_integration(smtp_server): controller, handler = smtp_server - email = IntermediateEmail( + email = Email( html="Hello World
", subject="Integration Test", recipients=["test@example.com"], @@ -47,7 +47,7 @@ def test_send_email_integration(smtp_server): ) # Send email to the test SMTP server - send_intermediate_email_with_smtp( + send_email_with_smtp( smtp_host="127.0.0.1", smtp_port=8025, username="test@example.com", diff --git a/nbmail/tests/test_ingress.py b/nbmail/tests/test_ingress.py index fea863a..148c4cd 100644 --- a/nbmail/tests/test_ingress.py +++ b/nbmail/tests/test_ingress.py @@ -4,23 +4,23 @@ from base64 import b64encode from nbmail.ingress import ( - redmail_to_intermediate_email, - yagmail_to_intermediate_email, - mjml_to_intermediate_email, - quarto_json_to_intermediate_email, - _email_message_to_intermediate_email, + redmail_to_email, + yagmail_to_email, + mjml_to_email, + quarto_json_to_email, + _email_message_to_email, ) -from nbmail.structs import IntermediateEmail +from nbmail.structs import Email -def test_email_message_to_intermediate_email_simple(): +def test_email_message_to_email_simple(): msg = EmailMessage() msg["Subject"] = "Test Subject" msg["To"] = "recipient@example.com" msg.set_content("Plain text") msg.add_alternative("HTML content
", subtype="html") - result = _email_message_to_intermediate_email(msg) + result = _email_message_to_email(msg) assert result.subject == "Test Subject" assert result.recipients == ["recipient@example.com"] @@ -30,7 +30,7 @@ def test_email_message_to_intermediate_email_simple(): assert result.external_attachments is None -def test_email_message_to_intermediate_email_multiple_recipients(): +def test_email_message_to_email_multiple_recipients(): msg = EmailMessage() msg["Subject"] = "Multi-recipient" msg["To"] = "to1@example.com, to2@example.com" @@ -38,7 +38,7 @@ def test_email_message_to_intermediate_email_multiple_recipients(): msg["Bcc"] = "bcc@example.com" msg.add_alternative("Test", subtype="html") - result = _email_message_to_intermediate_email(msg) + result = _email_message_to_email(msg) assert len(result.recipients) == 4 assert "to1@example.com" in result.recipients @@ -47,7 +47,7 @@ def test_email_message_to_intermediate_email_multiple_recipients(): assert "bcc@example.com" in result.recipients -def test_email_message_to_intermediate_email_with_inline_image(): +def test_email_message_to_email_with_inline_image(): msg = EmailMessage() msg["Subject"] = "With Image" msg.add_alternative("Quarto email
", "rsc_email_subject": "Quarto Test", @@ -233,7 +233,7 @@ def test_quarto_json_to_intermediate_email_basic(tmp_path): with open(json_file, "w") as f: json.dump(json_data, f) - result = quarto_json_to_intermediate_email(str(json_file)) + result = quarto_json_to_email(str(json_file)) assert result.subject == "Quarto Test" assert "Quarto email
" in result.html @@ -244,7 +244,7 @@ def test_quarto_json_to_intermediate_email_basic(tmp_path): assert result.rsc_email_supress_scheduled is False -def test_quarto_json_to_intermediate_email_minimal(tmp_path): +def test_quarto_json_to_email_minimal(tmp_path): json_data = { "rsc_email_body_html": "Minimal", "rsc_email_subject": "Minimal Subject", @@ -254,7 +254,7 @@ def test_quarto_json_to_intermediate_email_minimal(tmp_path): with open(json_file, "w") as f: json.dump(json_data, f) - result = quarto_json_to_intermediate_email(str(json_file)) + result = quarto_json_to_email(str(json_file)) assert result.subject == "Minimal Subject" assert result.html == "Minimal" @@ -265,7 +265,7 @@ def test_quarto_json_to_intermediate_email_minimal(tmp_path): assert result.rsc_email_supress_scheduled is False -def test_quarto_json_to_intermediate_email_empty_lists(tmp_path): +def test_quarto_json_to_email_empty_lists(tmp_path): """Test handling empty lists for attachments and images.""" json_data = { "rsc_email_body_html": "Test", @@ -279,7 +279,7 @@ def test_quarto_json_to_intermediate_email_empty_lists(tmp_path): with open(json_file, "w") as f: json.dump(json_data, f) - result = quarto_json_to_intermediate_email(str(json_file)) + result = quarto_json_to_email(str(json_file)) assert result.external_attachments == [] assert result.inline_attachments == {} diff --git a/nbmail/tests/test_structs.py b/nbmail/tests/test_structs.py index b60db3e..60d9847 100644 --- a/nbmail/tests/test_structs.py +++ b/nbmail/tests/test_structs.py @@ -1,11 +1,11 @@ import re import pytest -from nbmail.structs import IntermediateEmail +from nbmail.structs import Email def test_creation_with_text_and_attachments(): - email = IntermediateEmail( + email = Email( html="Hi
", subject="With Text and Attachments", text="Plain text version", @@ -21,7 +21,7 @@ def test_creation_with_text_and_attachments(): def test_creation_without_text_and_attachments(): - email = IntermediateEmail( + email = Email( html="Hi
", subject="No Text or Attachments", ) @@ -34,7 +34,7 @@ def test_creation_without_text_and_attachments(): def test_subject_inserts_after_body(tmp_path): html = "Hello!
" - email = IntermediateEmail( + email = Email( html=html, subject="Test Subject", rsc_email_supress_report_attachment=False, @@ -55,7 +55,7 @@ def test_subject_inserts_after_body(tmp_path): def test_subject_prepends_if_no_body(tmp_path): html = "Hello!
" - email = IntermediateEmail( + email = Email( html=html, subject="NoBody", ) @@ -68,7 +68,7 @@ def test_subject_prepends_if_no_body(tmp_path): def test_raises_on_external_attachments(tmp_path): html = "Test
" - email = IntermediateEmail( + email = Email( html=html, subject="Test", external_attachments=["file.txt"], @@ -88,7 +88,7 @@ def test_raises_on_external_attachments(tmp_path): ) def test_not_implemented_methods(method_name): """Test that unimplemented methods raise NotImplementedError.""" - email = IntermediateEmail( + email = Email( html="Hi
", subject="Test", ) @@ -99,7 +99,7 @@ def test_not_implemented_methods(method_name): def test_preview_email_simple_html(tmp_path, snapshot): html = "Hello World!
" - email = IntermediateEmail( + email = Email( html=html, subject="Simple Test Email", ) @@ -120,7 +120,7 @@ def test_preview_email_with_inline_attachments(tmp_path, snapshot):