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 with config.provide_service() as mailer:
    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

Event listeners in Litestar execute outside request context and cannot receive DI-injected dependencies. Pass the mailer explicitly:

from litestar import Litestar, 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",
)

@get("/register/{email:str}")
async def register(email: str, mailer: EmailService) -> dict[str, str]:
    # Pass the DI-injected mailer to the event
    request.app.emit("user.registered", email, mailer=mailer)
    return {"status": "queued"}

@listener("user.registered")
async def on_user_registered(email: str, mailer: EmailService) -> None:
    # mailer is passed explicitly from emit(), not injected via DI
    await mailer.send_message(
        EmailMessage(subject="Welcome!", body="Thanks for signing up.", to=[email]),
    )

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".

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 with config.provide_service() as mailer:
    await mailer.send_message(message)

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

async with config.provide_service() as mailer:
    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.2.0.tar.gz (187.7 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.2.0-py3-none-any.whl (24.5 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: litestar_email-0.2.0.tar.gz
  • Upload date:
  • Size: 187.7 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.2.0.tar.gz
Algorithm Hash digest
SHA256 f89b48cff0e514206755bea9ee1eb71fcede90befe02159bdce49df7b52cf896
MD5 23c232de762429ee32412593babad431
BLAKE2b-256 13ae8fde4b5656906647deba103dfb747f6e1a5750a6e52e621592ac52081e01

See more details on using hashes here.

Provenance

The following attestation bundles were made for litestar_email-0.2.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.2.0-py3-none-any.whl.

File metadata

  • Download URL: litestar_email-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 24.5 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.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 86f00685970ce32d4ef1153c35483bc7b4e1c4b18224f4278c94165d7ca4d810
MD5 61dd03fa480072e152f067f2b1048628
BLAKE2b-256 95d8f1588245c3a429810f732b91d6b7c061b138523f49879f0ff71526830b54

See more details on using hashes here.

Provenance

The following attestation bundles were made for litestar_email-0.2.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