advanced-alchemy
Use when working with advanced_alchemy, alembic/, SQLAlchemyAsyncRepositoryService, SQLAlchemyAsyncConfig, repository_type,…
Use when working with litestar_email, EmailPlugin, EmailConfig, EmailService, EmailMessage, SMTPConfig, ResendConfig, SendGridConfig, MailgunConfig, SESConfig. Not for marketing APIs — use vendor SDKs.
Claude Code
$ npx -y skills add litestar-org/litestar-skills --skill litestar-email --agent claude-code
Codex
$ npx skills add litestar-org/litestar-skills --skill litestar-email -a codex -y
Cursor
$ npx skills add litestar-org/litestar-skills --skill litestar-email -a cursor -y
Gemini CLI
$ npx skills add litestar-org/litestar-skills --skill litestar-email -a gemini-cli -y
GitHub Copilot
$ npx skills add litestar-org/litestar-skills --skill litestar-email -a github-copilot -y
OpenCode
$ npx skills add litestar-org/litestar-skills --skill litestar-email -a opencode -y
Windsurf
$ npx skills add litestar-org/litestar-skills --skill litestar-email -a windsurf -y
name: litestar-email description: "Use when working with litestar_email, EmailPlugin, EmailConfig, EmailService, EmailMessage, SMTPConfig, ResendConfig, SendGridConfig, MailgunConfig, SESConfig. Not for marketing APIs — use vendor SDKs."
`litestar-email` 0.4.0 provides one async sending interface for console, memory, SMTP, Resend, SendGrid, Mailgun, Amazon SES, and custom backends. Match the backend already selected by the project; keep message construction independent from the transport.
(or `FromDishka[EmailService]` when the project uses Dishka) for direct `EmailService` handler injection.
are list fields.
message and keep that I/O async.
pip install "litestar-email>=0.4.0" pip install "litestar-email[smtp]>=0.4.0" # aiosmtplib pip install "litestar-email[ses]>=0.4.0" # botocore for SigV4 pip install "litestar-email[httpx]>=0.4.0" # default HTTP transport pip install "litestar-email[aiohttp]>=0.4.0" # alternative HTTP transport
The HTTP API backends select `httpx` by default, but the transport is optional in `litestar-email` itself. Install the `httpx` or `aiohttp` extra (unless the project already provides that dependency), and select `aiohttp` only when the project standardizes on it.
from os import environ
from litestar import Litestar
from litestar_email import EmailConfig, EmailPlugin, SMTPConfig
email_config = EmailConfig(
backend=SMTPConfig(
host="smtp.example.com",
port=587,
username=environ["SMTP_USERNAME"],
password=environ["SMTP_PASSWORD"],
use_tls=True,
),
from_email="noreply@example.com",
from_name="Example App",
)
app = Litestar(plugins=[EmailPlugin(config=email_config)])`EmailConfig` fields:
| Field | Default | Contract | | --- | --- | --- | | `backend` | `"console"` | Registered name, import path, or built-in backend config object | | `from_email` | `"noreply@localhost"` | Default sender address | | `from_name` | `""` | Default display name | | `fail_silently` | `False` | Backend-specific best-effort delivery behavior | | `email_service_dependency_key` | `"mailer"` | Litestar DI key | | `email_service_state_key` | `"mailer"` | Key holding the config in app state |
The dependency and state keys occupy separate namespaces. Change them independently when the application already uses either key:
email_config = EmailConfig(
backend="memory",
email_service_dependency_key="email_service",
email_service_state_key="email_config",
)`EmailPlugin.on_app_init()` registers:
`EmailMultiAlternatives`, `EmailService`, `MailgunConfig`, `ResendConfig`, `SESConfig`, `SMTPConfig`, `SendGridConfig`) in Litestar's signature namespace;
Because `EmailConfig.provide_service()` is a synchronous method returning an `AsyncServiceProvider` instance rather than an `async def` generator function, Litestar's default `Provide(config.provide_service, sync_to_thread=False)` injects `AsyncServiceProvider` rather than `EmailService`.
To inject an open `EmailService` with request-scoped connection cleanup, bind `Provide(email_config.provide_service().__aiter__)` on the router, controller, or handler (or use Dishka's `FromDishka[EmailService]`):
from litestar import post
from litestar.di import NamedDependency, Provide
from litestar_email import EmailConfig, EmailMessage, EmailService
email_config = EmailConfig(backend="memory", from_email="noreply@example.com")
@post(
"/notifications",
dependencies={"mailer": Provide(email_config.provide_service().__aiter__)},
)
async def send_notification(
mailer: NamedDependency[EmailService],
) -> dict[str, int]:
sent = await mailer.send_message(
EmailMessage(
subject="Notification",
body="You have a new notification.",
to=["recipient@example.com"],
),
)
return {"sent": sent}If using the plugin's default dependency directly without overriding `dependencies`, register `signature_types=[AsyncServiceProvider]`, annotate the parameter as `mailer: NamedDependency[AsyncServiceProvider]`, and enter `async with mailer as service:` inside the handler.
If the project uses Dishka, yield `EmailService` from a `Scope.REQUEST` provider and inject `FromDishka[EmailService]`:
from collections.abc import AsyncIterator
from dishka import Provider, Scope
from dishka.integrations.litestar import FromDishka, inject
from litestar import post
from litestar_email import EmailConfig, EmailMessage, EmailService
def build_email_provider(config: EmailConfig) -> Provider:
async def provide_mailer() -> AsyncIterator[EmailService]:
async with config.provide_service() as mailer:
yield mailer
provider = Provider(scope=Scope.REQUEST)
provider.provide(provide_mailer)
return provider
@post("/welcome")
@inject
async def send_welcome(
email_service: FromDishka[EmailService],
) -> dict[str, int]:
sent = await email_service.send_message(
EmailMessage(subject="Welcome", body="Hello!", to=["user@example.com"]),
)
return {"sent": sent}App state does not contain a permanently open `EmailService`. Use `plugin.get_service(app.state
Opinionated, first-party agent skills, plugins, subagents, hooks, and rules for the Litestar framework and its ecosystem — published from a single-root repository across Google Antigravity, Claude Code, Codex CLI, Cursor, OpenCode, and VS Code / Copilot.
Use when working with advanced_alchemy, alembic/, SQLAlchemyAsyncRepositoryService, SQLAlchemyAsyncConfig, repository_type,…
Use when working with litestar_autowire, AutowirePlugin, AutowireConfig, domain_packages, AutowireIntegration, AutowireLoader, or…
Use when working with uv build, uv_build, hatch build, PyApp, scie-jump, PYAPP_*, wheel assets, GitHub release matrices,…
Use when working with Dockerfile, compose, Railway, Cloud Run, GKE, systemd, Kubernetes, Terraform, deploy scripts, or…
Use when working with zensical.toml, docs/conf.py, sphinx, shibuya, litestar-sphinx-theme, mkdocstrings, Griffe, objects.inv, or…
Use when working with litestar_granian, GranianPlugin, litestar run Granian options, runtime threads, HTTP/2, TLS, access logs,…
You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…
Ask which skill or flow fits your situation. A router over the skills in this repo.