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.3.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.3-py3-none-any.whl (11.7 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for abs_email_core-0.1.3.tar.gz
Algorithm Hash digest
SHA256 94d7de5def43db2c00c2ae7e2051c5dbd818aedfaca0e676ba7a686352596408
MD5 d3d4ebcd3c71d772db6438d9f8a60e17
BLAKE2b-256 496f07dea87f7df70f339a501a4db4e7dc9a4afb77ef0784e066eb0f6868359b

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for abs_email_core-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 7a5919e012b345521741ca31fe1126314e3dd693f3e86fb0db67f7a66a4a810b
MD5 5e50cb33c7f550470dd000a0adf3d0bb
BLAKE2b-256 e0cf4621e968d87dd4f8dca063e3781023c8569465788b09ff1805a0512656ed

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