Metadata-Version: 2.4
Name: herfy-push
Version: 1.0.0
Summary: Web Push SDK for Herfy applications — send browser push notifications via Control Center VAPID config
Project-URL: Homepage, https://github.com/Herfy-Food-Services/herfy-shared-library
Project-URL: Documentation, https://github.com/Herfy-Food-Services/herfy-shared-library/tree/master/herfy-push
Author: Herfy Development Team
License-Expression: MIT
Keywords: control-center,herfy,push,vapid,web-push
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.9
Requires-Dist: httpx>=0.24.0
Requires-Dist: pywebpush>=1.14.0
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
Requires-Dist: pytest>=7.0.0; extra == 'dev'
Requires-Dist: respx>=0.20.0; extra == 'dev'
Description-Content-Type: text/markdown

# herfy-push

Web Push SDK for Herfy applications. Send browser push notifications using only your Control Center `client_id` and `client_secret` — no VAPID private key handling in app config.

## Installation

```bash
pip install herfy-push
```

## Usage

```python
from herfy_push import HerfyPushClient, AsyncHerfyPushClient

# Sync
client = HerfyPushClient.from_credentials(
    client_id="app_customer_care",
    client_secret="your_secret",
    control_center_url="https://cc.herfy.com",
)
client.send(
    subscription={"endpoint": "...", "keys": {"p256dh": "...", "auth": "..."}},
    payload={"title": "SLA breach", "body": "Ticket #123", "url": "https://app/tickets/123"},
)

# Async (FastAPI)
client = AsyncHerfyPushClient.from_env()
await client.send(subscription=..., payload=...)
public_key = await client.get_public_key()  # hand to the browser's pushManager.subscribe()
```

## How it works

1. SDK authenticates with Control Center via `POST /oauth/token` (cached, TTL configurable via `PUSH_TOKEN_CACHE_TTL`).
2. SDK fetches VAPID keys from `GET /api/config/push` (cached for the client's process lifetime).
3. SDK sends directly to the browser's push service via the Web Push protocol (`pywebpush`) — no further Control Center round-trip per send.

## Error handling

- `AuthError` — Control Center rejected the client credentials.
- `ConfigError` — Control Center push config endpoint failed or is missing VAPID keys.
- `PushSubscriptionExpiredError` — the push service returned 404/410: the subscription is dead, delete it from your database.
- `SendError` — any other send failure.

## Environment variables

- `CONTROL_CENTER_URL`, `AUTH_CLIENT_ID`, `AUTH_CLIENT_SECRET` — required, used by `.from_env()`.
- `PUSH_TOKEN_CACHE_TTL` (default `240`), `PUSH_REQUEST_TIMEOUT` (default `15`) — optional.
