Skip to main content

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

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)

Source distribution for mpt-extension-contrib-custom-notifications 1.2.0
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)

Table of built distributions (wheels) for mpt-extension-contrib-custom-notifications 1.2.0
File Interpreter ABI Platform Actions
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.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page