Skip to main content

Core email utilities with pluggable provider support and Jinja2 template rendering

Project description

abs-email-core

Core email utilities with pluggable provider support, Jinja2 template rendering, and Quill HTML sanitization.

Installation

pip install abs-email-core

# With SendGrid support
pip install "abs-email-core[sendgrid]"

Quick Start

from abs_email_core import SendGridProvider, TemplateService, SendMailRequest

# Initialize provider and template service
provider = SendGridProvider(api_key="your-api-key", from_email="noreply@example.com")
templates = TemplateService(template_dir="/path/to/your/templates")

# Render and send an HTML email
html = templates.render_email_template(title="Welcome", content="<p>Hello!</p>")
request = SendMailRequest(to=["user@example.com"], subject="Welcome", body=html)
provider.send_html_email(request)

Schemas

SendMailRequest

Field Type Required Description
to List[EmailStr] Yes Recipient email addresses
subject str Yes Email subject line
body str Yes Email body (plain text or HTML)
from_email EmailStr No Override the provider's default from address
cc List[EmailStr] No CC recipients (default: [])
bcc List[EmailStr] No BCC recipients (default: [])

FileAttachment

Field Type Required Description
file_name str Yes Display name of the attachment
url str Yes URL to the file
file_id str No Optional identifier for the file

Providers

SendGridProvider

Requires the sendgrid extra: pip install "abs-email-core[sendgrid]"

from abs_email_core import SendGridProvider, SendMailRequest

provider = SendGridProvider(api_key="SG.xxx", from_email="noreply@example.com")

# Plain text email
request = SendMailRequest(to=["user@example.com"], subject="Hello", body="Hi there!")
provider.send_email(request)

# HTML email
request = SendMailRequest(to=["user@example.com"], subject="Hello", body="<h1>Hi!</h1>")
provider.send_html_email(request)

# With file attachments (UploadFile-like objects)
provider.send_email(request, attachments=[upload_file])

Custom Provider

Implement the EmailProvider abstract class to add support for other email services:

from abs_email_core.provider.base import EmailProvider

class SMTPProvider(EmailProvider):
    def __init__(self, host: str, port: int, username: str, password: str, from_email: str):
        self.host = host
        self.port = port
        self.username = username
        self.password = password
        self.from_email = from_email

    def send_email(self, request, attachments=None) -> bool:
        # SMTP implementation
        ...

    def send_html_email(self, request, attachments=None) -> bool:
        # SMTP HTML implementation
        ...

Template Service

TemplateService uses Jinja2 to render email templates. The template_dir parameter is required — point it to the directory containing your Jinja2 template files.

from abs_email_core import TemplateService

templates = TemplateService(template_dir="/path/to/your/templates")

# Render any template by filename
html = templates.render_template("welcome.html", name="John", code="ABC123")

# Shortcut for the bundled email_template.html (must exist in your template_dir)
html = templates.render_email_template(
    title="Welcome",
    content="<p>Your account is ready.</p>",
    footer="GovAssist Inc.",    # optional: footer text
    logo_url="https://...",     # optional: header/footer logo image URL
    attachments=[               # optional: renders download links
        {"file_name": "report.pdf", "url": "https://example.com/report.pdf"},
    ],
)

A default email_template.html is shipped with the package under abs_email_core/templates/ — copy it into your service's template directory or use it as a starting point for customization.

Quill HTML Sanitization

When email content originates from a Quill rich-text editor, the raw HTML often contains structural issues. TemplateService provides built-in sanitization that fixes:

  • Removes internal ql-ui spans injected by Quill
  • Normalizes list tags based on data-list attribute (bullet<ul>, ordered<ol>)
  • Splits mixed lists (bullet + ordered items in one tag) into separate correct tags
  • Merges consecutive same-type lists separated by <br> or whitespace
  • Cleans data-list attributes from <li> elements
  • Fixes fragmented paragraphs (e.g. <p>Dear </p>Name<p>,</p><p>Dear Name,</p>)

Usage

# Option 1: Sanitize during template rendering
html = templates.render_email_template(
    title="Welcome",
    content=quill_html,
    sanitize_quill=True,  # enables Quill HTML sanitization before rendering
)

# Option 2: Sanitize standalone (without rendering a template)
clean_html = templates.sanitize_quill_html(quill_html)

Utilities

Parse Emails

TemplateService includes a helper to parse email addresses from strings or lists:

# From comma/newline-separated string
emails = templates._parse_emails("a@example.com, b@example.com\nc@example.com")
# → ["a@example.com", "b@example.com", "c@example.com"]

# From list (passthrough)
emails = templates._parse_emails(["a@example.com", "b@example.com"])
# → ["a@example.com", "b@example.com"]

Dependency Injection (with dependency-injector)

from dependency_injector import containers, providers
from abs_email_core import SendGridProvider, TemplateService

class Container(containers.DeclarativeContainer):
    email_provider = providers.Factory(
        SendGridProvider,
        api_key=configs.SENDGRID_API_KEY,
        from_email=configs.EMAIL_FROM,
    )
    template_service = providers.Factory(
        TemplateService,
        template_dir=configs.EMAIL_TEMPLATE_DIR,
    )

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

abs_email_core-0.1.1.tar.gz (10.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

abs_email_core-0.1.1-py3-none-any.whl (11.7 kB view details)

Uploaded Python 3

File details

Details for the file abs_email_core-0.1.1.tar.gz.

File metadata

  • Download URL: abs_email_core-0.1.1.tar.gz
  • Upload date:
  • Size: 10.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.1.2 CPython/3.13.7 Darwin/23.6.0

File hashes

Hashes for abs_email_core-0.1.1.tar.gz
Algorithm Hash digest
SHA256 8e1760a25ae86421fac9d2c7db9cb8fec5a307e6feaaa00950709d91b099bf05
MD5 13a3b0dc764a7511b95ef8c7eaed88c6
BLAKE2b-256 b6d9b8a19a01a2869f39c2f139754b724d3e433fc95a8e32d06e7546464994b8

See more details on using hashes here.

File details

Details for the file abs_email_core-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: abs_email_core-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 11.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.1.2 CPython/3.13.7 Darwin/23.6.0

File hashes

Hashes for abs_email_core-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 f42681768a8b736fd327f9408479ae67dc23e8f62e5cadab3b4e613823df2b80
MD5 8cbc49cc62c8685bc61c0fc8f9860c44
BLAKE2b-256 5fb658856e8148682afef9fa4dc08736b8d86251365aa02e3e8bc0875a67b144

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page