Coverage for src / lexigram / contracts / notification / protocols.py: 100%
12 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-08-19 05:41 +0800
« prev ^ index » next coverage.py v7.13.5, created at 2026-08-19 05:41 +0800
1# lexigram-contracts/src/lexigram/contracts/notification/protocols.py
2"""Notification channel protocols."""
4from __future__ import annotations
6from typing import TYPE_CHECKING, Protocol, runtime_checkable
8if TYPE_CHECKING:
9 from lexigram.contracts.core.health import HealthCheckResult
10 from lexigram.contracts.core.result import Result
11 from lexigram.contracts.mailer.types import MessageDeliveryReceipt
12 from lexigram.contracts.notification.errors import NotificationError
13 from lexigram.contracts.notification.types import PushMessage, SMSMessage
16@runtime_checkable
17class SMSChannelProtocol(Protocol):
18 """Structural protocol for SMS backends (Twilio, Vonage, etc.).
20 ``send()`` returns ``Ok(receipt)`` on acceptance or ``Err(NotificationError)``
21 for expected failures. Infrastructure failures must be raised as exceptions.
22 """
24 async def send(
25 self, message: SMSMessage
26 ) -> Result[MessageDeliveryReceipt, NotificationError]:
27 """Send an SMS message.
29 Args:
30 message: The SMS to deliver.
32 Returns:
33 ``Ok(MessageDeliveryReceipt)`` or ``Err(NotificationError)``.
34 """
35 ...
37 async def health_check(self, timeout: float = 5.0) -> HealthCheckResult:
38 """Check SMS backend connectivity."""
39 ...
42@runtime_checkable
43class PushChannelProtocol(Protocol):
44 """Structural protocol for push notification backends (FCM, APNS, etc.).
46 ``send()`` delivers to one or more device tokens. ``send_batch()`` delivers
47 to multiple tokens in one API call where the provider supports it.
48 """
50 async def send(
51 self, message: PushMessage
52 ) -> Result[MessageDeliveryReceipt, NotificationError]:
53 """Send a push notification to one or more device tokens.
55 Args:
56 message: The push notification to deliver.
58 Returns:
59 ``Ok(MessageDeliveryReceipt)`` or ``Err(NotificationError)``.
60 """
61 ...
63 async def send_batch(
64 self, messages: list[PushMessage]
65 ) -> list[Result[MessageDeliveryReceipt, NotificationError]]:
66 """Send push notifications in bulk.
68 Args:
69 messages: List of push notifications to deliver.
71 Returns:
72 List of ``Result`` values, one per message, preserving order.
73 """
74 ...
76 async def health_check(self, timeout: float = 5.0) -> HealthCheckResult:
77 """Check push backend connectivity."""
78 ...
81__all__ = ["PushChannelProtocol", "SMSChannelProtocol"]