Metadata-Version: 2.4
Name: ravenrelay
Version: 0.1.1
Summary: Server-side Python SDK for the RavenRelay email API
Author: RavenRelay
License-Expression: LicenseRef-Proprietary
Project-URL: Repository, https://github.com/joshmoy/raven-relay
Project-URL: Documentation, https://github.com/joshmoy/raven-relay/blob/main/sdks/python/README.md
Keywords: email,transactional-email,sdk,webhooks
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Operating System :: OS Independent
Classifier: Topic :: Communications :: Email
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.9
Description-Content-Type: text/markdown

# RavenRelay Python SDK

Server-side Python 3.9+ client, using only the standard library. No runtime dependencies.

Version 0.1.0 is published on PyPI. Install with:

```sh
python -m pip install ravenrelay
```

Repository development installation:

```sh
# Source builds require Python 3.10+ for the patched setuptools backend.
pip install ./sdks/python
```

```python
import os
from ravenrelay import RavenRelay, RavenRelayError, verify_webhook_signature

client = RavenRelay(os.environ['RAVENRELAY_API_KEY'], base_url=os.environ['RAVENRELAY_API_URL'])
result = client.emails.send({'from': 'hello@example.com', 'to': 'user@example.com',
                            'subject': 'Welcome', 'text': 'Hello'}, idempotency_key='welcome-123')
email = client.emails.get(result['id'])
page = client.emails.list(status='sent', recipient='user@example.com', cursor=None)
```

Use `template` and `variables` instead of subject/body for saved project templates. Responses preserve the API's JSON field names and extra fields. `RavenRelayError` exposes `status` and `code`; `TransportError` means acceptance may be uncertain, and `ProtocolError` indicates an invalid successful response. No automatic retries. Reuse an idempotency key and identical body when retrying a send. The default origin is `https://api.getravenrelay.com`; set your actual deployed origin explicitly. Default total request timeout: 10 seconds, including response reads. Redirects are refused. Keep API keys server-side.

Webhook verification accepts original bytes or UTF-8 text and uses a five-minute timestamp tolerance, constant-time comparison, and HMAC-SHA256. Pass header strings unchanged, verify before parsing JSON, then durably deduplicate event IDs. `now` is Unix time in seconds for tests.

```sh
python3 sdks/testing/contract_server.py python3 sdks/python/tests/contract.py
```

Release preparation and the manual Trusted Publishing workflow are documented in `docs/python-sdk-publishing.md`. The first release is `0.1.0`; the repository may contain changes ahead of PyPI. No reuse license has been granted.

Security: remote origins must use HTTPS. Plain HTTP is accepted only for literal `localhost`, `127.0.0.1` and IPv6 loopback hosts. Credentials/query/fragment, whitespace and backslashes are rejected in API origins. Authentication/idempotency headers must be printable ASCII; `.` and `..` email IDs are rejected. Response bodies are limited to 16 MiB, valid UTF-8 and 64 JSON nesting levels. TLS certificate verification stays enabled. Use vendor-supported runtimes with current security patches; the compatibility floor does not promise that an old runtime is secure. See `docs/sdk-security-review.md` for dependency and release controls.
