Skip to content

Push Notifications

Web Push notification subscription management.

This module handles push notification subscriptions from client browsers using the Web Push protocol (RFC 8030). Subscriptions include endpoint URLs and encryption keys for secure message delivery.

Warning

Subscriptions are currently stored in-memory and will be lost on restart. Production deployment should use PostgreSQL or Redis for persistence.

Example

Client subscribes: POST /push/subscribe {"endpoint": "https://...", "keys": {"p256dh": "...", "auth": "..."}}

SUBSCRIPTIONS module-attribute

SUBSCRIPTIONS = []

List of active push subscriptions. WARNING: In-memory storage only.

PushKeys

Bases: BaseModel

Encryption keys for Web Push messages.

Attributes:

Name Type Description
p256dh str

Public key for message encryption (Base64).

auth str

Authentication secret for message encryption (Base64).

Source code in app/push.py
29
30
31
32
33
34
35
36
37
38
class PushKeys(BaseModel):
    """Encryption keys for Web Push messages.

    Attributes:
        p256dh: Public key for message encryption (Base64).
        auth: Authentication secret for message encryption (Base64).
    """

    p256dh: str
    auth: str

PushSubscription

Bases: BaseModel

Web Push subscription from a client browser.

Attributes:

Name Type Description
endpoint str

Push service endpoint URL (browser-specific).

expirationTime int | None

Optional subscription expiry timestamp.

keys PushKeys

Encryption keys for secure message delivery.

Source code in app/push.py
41
42
43
44
45
46
47
48
49
50
51
52
class PushSubscription(BaseModel):
    """Web Push subscription from a client browser.

    Attributes:
        endpoint: Push service endpoint URL (browser-specific).
        expirationTime: Optional subscription expiry timestamp.
        keys: Encryption keys for secure message delivery.
    """

    endpoint: str
    expirationTime: int | None = None
    keys: PushKeys

subscribe

subscribe(sub)

Register a new push notification subscription.

De-duplicates by endpoint URL to prevent duplicate subscriptions.

Parameters:

Name Type Description Default
sub PushSubscription

Push subscription from browser's Push API.

required

Returns:

Name Type Description
dict dict[str, bool | int]

Status with ok=True and total subscription count.

Source code in app/push.py
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
@router.post("/subscribe")
def subscribe(sub: PushSubscription) -> dict[str, bool | int]:
    """Register a new push notification subscription.

    De-duplicates by endpoint URL to prevent duplicate subscriptions.

    Args:
        sub: Push subscription from browser's Push API.

    Returns:
        dict: Status with ok=True and total subscription count.
    """
    # de-duplicate by endpoint
    if not any(s["endpoint"] == sub.endpoint for s in SUBSCRIPTIONS):
        SUBSCRIPTIONS.append(sub.model_dump())
    return {"ok": True, "count": len(SUBSCRIPTIONS)}