Skip to content

Commit

Permalink
Merge branch '2.x' into bump-anyio-2.x
Browse files Browse the repository at this point in the history
  • Loading branch information
abrookins authored Jul 29, 2024
2 parents 1cf386a + 9303883 commit 80a9bc2
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 4 deletions.
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

aiosqlite >= 0.17.0
alembic >= 1.7.5, < 2.0.0
apprise >= 1.1.0, < 2.0.0
apprise >= 1.8.0, < 2.0.0
asyncpg >= 0.23
click >= 8.0, < 8.2
cryptography >= 36.0.1
Expand Down
30 changes: 28 additions & 2 deletions src/prefect/blocks/notifications.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,12 +139,38 @@ class MicrosoftTeamsWebhook(AppriseNotificationBlock):
url: SecretStr = Field(
...,
title="Webhook URL",
description="The Teams incoming webhook URL used to send notifications.",
description="The Microsoft Power Automate (Workflows) URL used to send notifications to Teams.",
examples=[
"https://your-org.webhook.office.com/webhookb2/XXX/IncomingWebhook/YYY/ZZZ"
"https://prod-NO.LOCATION.logic.azure.com:443/workflows/WFID/triggers/manual/paths/invoke?sp=%2Ftriggers%2Fmanual%2Frun&sv=1.0&sig=SIGNATURE"
],
)

include_image: bool = Field(
default=True,
description="Include an image with the notification.",
)

wrap: bool = Field(
default=True,
description="Wrap the notification text.",
)

def block_initialization(self) -> None:
"""see https://github.com/caronc/apprise/pull/1172"""
from apprise.plugins.workflows import NotifyWorkflows

if not (
parsed_url := NotifyWorkflows.parse_native_url(self.url.get_secret_value())
):
raise ValueError("Invalid Microsoft Teams Workflow URL provided.")

parsed_url |= { # novermin
"include_image": self.include_image,
"wrap": self.wrap,
}

self._start_apprise_client(SecretStr(NotifyWorkflows(**parsed_url).url()))


class PagerDutyWebHook(AbstractAppriseNotificationBlock):
"""
Expand Down
55 changes: 54 additions & 1 deletion tests/blocks/test_notifications.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
CustomWebhookNotificationBlock,
DiscordWebhook,
MattermostWebhook,
MicrosoftTeamsWebhook,
OpsgenieWebhook,
PagerDutyWebHook,
SendgridEmail,
Expand All @@ -39,7 +40,12 @@ def reload_modules():

# A list of the notification classes Pytest should use as parameters to each method in TestAppriseNotificationBlock
notification_classes = sorted(
AppriseNotificationBlock.__subclasses__(), key=lambda cls: cls.__name__
[
cls
for cls in AppriseNotificationBlock.__subclasses__()
if cls != MicrosoftTeamsWebhook
],
key=lambda cls: cls.__name__,
)


Expand Down Expand Up @@ -702,3 +708,50 @@ def test_is_picklable(self):
pickled = cloudpickle.dumps(block)
unpickled = cloudpickle.loads(pickled)
assert isinstance(unpickled, SendgridEmail)


class TestMicrosoftTeamsWebhook:
SAMPLE_URL = "https://prod-NO.LOCATION.logic.azure.com:443/workflows/WFID/triggers/manual/paths/invoke?sp=%2Ftriggers%2Fmanual%2Frun&sv=1.0&sig=SIGNATURE"

async def test_notify_async(self):
with patch("apprise.Apprise", autospec=True) as AppriseMock:
apprise_instance_mock = AppriseMock.return_value
apprise_instance_mock.async_notify = AsyncMock()

block = MicrosoftTeamsWebhook(url=self.SAMPLE_URL)
await block.notify("test")

AppriseMock.assert_called_once()
apprise_instance_mock.add.assert_called_once_with(
"workflow://prod-NO.LOCATION.logic.azure.com:443/WFID/SIGNATURE/"
"?image=yes&wrap=yes"
"&format=markdown&overflow=upstream&rto=4.0&cto=4.0&verify=yes"
)
apprise_instance_mock.async_notify.assert_awaited_once_with(
body="test", title=None, notify_type=PREFECT_NOTIFY_TYPE_DEFAULT
)

def test_notify_sync(self):
with patch("apprise.Apprise", autospec=True) as AppriseMock:
apprise_instance_mock = AppriseMock.return_value
apprise_instance_mock.async_notify = AsyncMock()

block = MicrosoftTeamsWebhook(url=self.SAMPLE_URL)

block.notify("test")

AppriseMock.assert_called_once()
apprise_instance_mock.add.assert_called_once_with(
"workflow://prod-NO.LOCATION.logic.azure.com:443/WFID/SIGNATURE/"
"?image=yes&wrap=yes"
"&format=markdown&overflow=upstream&rto=4.0&cto=4.0&verify=yes"
)
apprise_instance_mock.async_notify.assert_called_once_with(
body="test", title=None, notify_type=PREFECT_NOTIFY_TYPE_DEFAULT
)

def test_is_picklable(self):
block = MicrosoftTeamsWebhook(url=self.SAMPLE_URL)
pickled = cloudpickle.dumps(block)
unpickled = cloudpickle.loads(pickled)
assert isinstance(unpickled, MicrosoftTeamsWebhook)

0 comments on commit 80a9bc2

Please sign in to comment.