Skip to main content

Email plugin for Litestar

Project description

litestar-email

Email support for Litestar applications. This plugin provides a pluggable email backend system for sending transactional emails with support for multiple providers.

Installation

pip install litestar-email

Usage

from litestar import Litestar
from litestar_email import EmailConfig, EmailPlugin

config = EmailConfig(
    backend="console",  # or "memory", "smtp", "sendgrid", "resend"
    from_email="noreply@example.com",
    from_name="My App",
)

app = Litestar(plugins=[EmailPlugin(config=config)])

Sending Email

from litestar_email import EmailMessage

message = EmailMessage(
    subject="Welcome!",
    body="Thanks for signing up.",
    to=["user@example.com"],
)

async for mailer in config.provide_service():
    await mailer.send_message(message)

If message.from_email is omitted, the service uses config.from_email and config.from_name as defaults.

Dependency Injection

The plugin registers a mailer dependency for handlers by default:

from litestar import get
from litestar_email import EmailMessage, EmailService

@get("/welcome/{email:str}")
async def send_welcome(email: str, mailer: EmailService) -> dict[str, str]:
    message = EmailMessage(
        subject="Welcome!",
        body="Thanks for signing up.",
        to=[email],
    )
    await mailer.send_message(message)
    return {"status": "sent"}

This works for both router handlers and controller methods the same way, since the dependency is registered on the app.

If you need a service outside of Litestar (e.g., for a worker), use config.get_service() for a one-off instance or config.provide_service() for batch sending.

Events and Listeners

Litestar listeners do not support DI, so pass the service explicitly when emitting:

from litestar import Litestar, Request, get
from litestar.events import listener
from litestar_email import EmailConfig, EmailMessage, EmailPlugin, EmailService

config = EmailConfig(
    backend="smtp",
    from_email="noreply@example.com",
    from_name="My App",
)

@listener("user.registered")
async def on_user_registered(email: str, mailer: EmailService) -> None:
    message = EmailMessage(
        subject="Welcome!",
        body="Thanks for signing up.",
        to=[email],
    )
    await mailer.send_message(message)

@get("/register/{email:str}")
async def register(email: str, request: Request) -> dict[str, str]:
    request.app.emit(
        "user.registered",
        email,
        mailer=config.get_service(request.app.state),
    )
    return {"status": "queued"}

app = Litestar(
    plugins=[EmailPlugin(config=config)],
    listeners=[on_user_registered],
)

You can override the dependency and state keys via EmailConfig if needed: email_service_dependency_key="email_service" and email_service_state_key="email_service". If you have the plugin instance available, use plugin.get_service(request.app.state).

Standalone (No Litestar)

Use the config helpers directly without Litestar:

from litestar_email import EmailConfig, EmailMessage

config = EmailConfig(backend="smtp", from_email="noreply@example.com")
message = EmailMessage(
    subject="Hello!",
    body="This is a standalone send.",
    to=["user@example.com"],
)

async for mailer in config.provide_service():
    await mailer.send_message(message)

For batch sends, use the context helper to reuse the connection:

async for mailer in config.provide_service():
    await mailer.send_messages([message1, message2, message3])

HTML Email

from litestar_email import EmailMultiAlternatives

message = EmailMultiAlternatives(
    subject="Welcome!",
    body="Thanks for signing up.",  # Plain text fallback
    html_body="<h1>Welcome!</h1><p>Thanks for signing up.</p>",
    to=["user@example.com"],
)

Available Backends

Backend Description Use Case
console Prints emails to stdout Development
memory Stores emails in memory Testing
smtp Async SMTP via aiosmtplib Production
sendgrid SendGrid HTTP API Production
resend Resend HTTP API Production

Testing

The InMemoryBackend is designed for testing:

from litestar_email.backends import InMemoryBackend

def test_sends_welcome_email():
    InMemoryBackend.clear()

    # ... code that sends email ...

    assert len(InMemoryBackend.outbox) == 1
    assert InMemoryBackend.outbox[0].subject == "Welcome!"

If you need direct backend access in tests, use config.get_backend():

from litestar_email import EmailConfig, EmailMessage

config = EmailConfig(backend="memory")
backend = config.get_backend()

message = EmailMessage(subject="Hello", body="Body", to=["user@example.com"])
await backend.send_messages([message])

Development

make install    # Install dependencies
make test       # Run tests
make lint       # Run linting
make check-all  # Run all checks

License

MIT

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

litestar_email-0.1.0.tar.gz (187.0 kB view details)

Uploaded Source

Built Distribution

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

litestar_email-0.1.0-py3-none-any.whl (23.7 kB view details)

Uploaded Python 3

File details

Details for the file litestar_email-0.1.0.tar.gz.

File metadata

  • Download URL: litestar_email-0.1.0.tar.gz
  • Upload date:
  • Size: 187.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for litestar_email-0.1.0.tar.gz
Algorithm Hash digest
SHA256 75ac56b0a300b980c58b7041be495a77efaf5e18e685400765c9b7cc0f62edb5
MD5 1e70a3681bc4525ca411db7a1ea5de9f
BLAKE2b-256 cad08c7d83fa2ea1c805943345e24d560b4cafcff509217945ed5cebef06d0b9

See more details on using hashes here.

Provenance

The following attestation bundles were made for litestar_email-0.1.0.tar.gz:

Publisher: publish.yml on cofin/litestar-email

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file litestar_email-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: litestar_email-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 23.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for litestar_email-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 71a05dc214b36459a286bf6b74a94338b147ddcf47f7a56691c17edf0a7254bd
MD5 e1a72f66cdb1071f03498f2b3caaefeb
BLAKE2b-256 29147b8341ba35215babe1a9bf6ff244eccfb33cb97fe578e5dc7414f35ac5d9

See more details on using hashes here.

Provenance

The following attestation bundles were made for litestar_email-0.1.0-py3-none-any.whl:

Publisher: publish.yml on cofin/litestar-email

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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