mpt-extension-contrib-custom-notifications
Shared notification channels for SoftwareONE MPT extensions built on the
Extension SDK. Extensions report to a channel (Microsoft Teams or AWS SES email)
through one registry — ctx.notifications — instead of re-implementing a sender
per extension.
Channels are pluggable: each is gated by an optional-dependency extra and self-registers through an entry point, so a base install pulls no channel dependencies and only the channels you install and configure are exposed.
It consolidates the per-extension notification code previously re-implemented in
the AWS (swo/notifications/teams.py) and Adobe (adobe_vipm/notifications.py)
extensions.
See AGENTS.md for the module documentation map.
Install
pip install "mpt-extension-contrib-custom-notifications[teams,ses]"
The base distribution has no channel dependencies. Each channel is an extra:
| Extra | Pulls in | Channel key |
|---|---|---|
teams |
microsoft-teams-cards, httpx |
teams |
ses |
boto3, jinja2 |
aws_ses |
Public API
mpt_extension_contrib.custom_notifications exposes the core; channel implementations
live under mpt_extension_contrib.custom_notifications.channels.<name>.
| Object | Purpose |
|---|---|
NotificationsContextMixin |
Adds self.notifications to an SDK context, built from settings. |
NotificationRegistry |
Named lookup of configured channels (register, get). |
build_registry(settings) |
Discover installed channels and register the configured ones. |
Notification |
Marker base class every notifier base class extends (get's bound). |
NotificationChannel |
Entry-point descriptor (name, build) advertised by a channel. |
NotificationSettings |
Marker Protocol for the settings a channel factory reads. |
Teams channel — mpt_extension_contrib.custom_notifications.channels.teams (extra teams):
| Object | Purpose |
|---|---|
TeamsNotifications |
Send Adaptive Cards to a Teams channel via a Workflows webhook (send_*). |
TeamsNotifier |
Base class a custom Teams implementation subclasses (the registry resolves by inheritance). |
TeamsSettings |
Protocol describing the settings the channel reads (teams_webhook_url, teams_notifications_enabled). |
Button, FactsSection |
Value types for a card link button and a facts section. |
Async Teams channel — mpt_extension_contrib.custom_notifications.channels.teams_async (channel teams_async, extra teams):
| Object | Purpose |
|---|---|
AsyncTeamsNotifications |
Send Adaptive Cards over httpx.AsyncClient without blocking the event loop (send_*). |
AsyncTeamsNotifier |
Base class for the async send_* methods; resolve via ctx.notifications.get(AsyncTeamsNotifier). |
SES channel — mpt_extension_contrib.custom_notifications.channels.ses (extra ses):
| Object | Purpose |
|---|---|
SesNotifications |
Send HTML emails through AWS SES (send_email / send_template -> bool). |
SesNotifier |
Base class a custom SES implementation subclasses (the registry resolves by inheritance). |
SesSettings |
Protocol for the settings the channel reads (region, sender, credentials, enable flag). |
EmailNotificationTemplate |
Subject + Jinja2 HTML body (render(context); from_file(subject, body_path) to load the body from an .html file). |
Async SES channel — mpt_extension_contrib.custom_notifications.channels.ses_async (channel aws_ses_async, extra ses):
| Object | Purpose |
|---|---|
AsyncSesNotifications |
Send HTML emails through AWS SES off the event loop via asyncio.to_thread (send_email / send_template -> bool). |
AsyncSesNotifier |
Base class for the async send_* methods; resolve via ctx.notifications.get(AsyncSesNotifier). |
Usage
Make the extension settings satisfy each installed channel's settings protocol
(inherit it so the contract is type-checked), then mix NotificationsContextMixin
into the context — it reads the standard ext_settings, so no extra wiring:
from dataclasses import dataclass
from mpt_extension_sdk.settings.extension import BaseExtensionSettings
from mpt_extension_contrib.custom_notifications import NotificationsContextMixin
from mpt_extension_contrib.custom_notifications.channels.teams import TeamsSettings
@dataclass(frozen=True)
class ExtensionSettings(BaseExtensionSettings, TeamsSettings):
# MSTEAMS_WEBHOOK_URL is read from the extension configuration.
teams_webhook_url: str | None = None
class OrderContext(NotificationsContextMixin, SdkOrderContext): ...
Then resolve a channel and send. get(NotifierProtocol) returns the registered
channel that satisfies the protocol, typed as that protocol:
from mpt_extension_contrib.custom_notifications.channels.teams import (
Button,
FactsSection,
TeamsNotifier,
)
teams = ctx.notifications.get(TeamsNotifier)
teams.send_error(
"Agreement sync failed",
str(exc),
button=Button(label="Open agreement", url=agreement_url),
facts=FactsSection(title="Context", entries={"Agreement": agreement_id}),
)
A channel appears in the registry only when both its extra is installed and
its enable flag (teams_notifications_enabled / email_notifications_enabled)
is on. get(...) on a channel that is not registered raises KeyError. Enabling
a channel without its required fields (teams_webhook_url / aws_ses_sender)
makes build_registry raise a clear ValueError, so a misconfiguration fails
loudly instead of silently disabling notifications.
Custom channels
A custom implementation inherits the channel Protocol (the registry matches
by inheritance); register it under any key (use override=True to replace a
built-in):
class MyTeamsNotifications(TeamsNotifier): ...
ctx.notifications.register("teams", MyTeamsNotifications(...), override=True)
To make a custom channel discoverable across extensions, ship it as its own
distribution that advertises a mpt_extension_contrib.custom_notifications.channels
entry point exposing a NotificationChannel.
Documentation
- Usage — install, configure, send, and write your own channel
- Architecture
- Contributing
- Testing
- Releases
Metadata
Release files for mpt-extension-contrib-custom-notifications 1.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| mpt_extension_contrib_custom_notifications-1.2.0.tar.gz | 14.8 kB | Without provenance | Details for mpt_extension_contrib_custom_notifications-1.2.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| mpt_extension_contrib_custom_notifications-1.2.0-py3-none-any.whl | Python 3 | none | any | Details for mpt_extension_contrib_custom_notifications-1.2.0-py3-none-any.whl |
Total release size: 36.5 kB
Release files / mpt_extension_contrib_custom_notifications-1.2.0.tar.gz
| Download URL | mpt_extension_contrib_custom_notifications-1.2.0.tar.gz |
|---|---|
| Size | 14.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
527789f1455a04c3dc84365e99419bc6b080b9b158fae23d84d3b0daa07b6190
|
|
BLAKE2b-256 checksum How to use checksums |
2b72d248e6fe39ee0d2385c670eaf59c66b58bee87225bf8def8685df77b6111
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / mpt_extension_contrib_custom_notifications-1.2.0-py3-none-any.whl
| Download URL | mpt_extension_contrib_custom_notifications-1.2.0-py3-none-any.whl |
|---|---|
| Size | 21.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
708538f178b9ad71b0ded8a97d5ddc3f332e5a39fff6991db4db725c8394ca2b
|
|
BLAKE2b-256 checksum How to use checksums |
d80c212419dd26ae9e7cb852eb7b3a390065384006a3fceb8283fdaaa9bb6b29
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for mpt-extension-contrib-custom-notifications 1.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.