primitivedotdev 0.1.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- primitivedotdev-0.1.1/.gitignore +19 -0
- primitivedotdev-0.1.1/PKG-INFO +183 -0
- primitivedotdev-0.1.1/README.md +157 -0
- primitivedotdev-0.1.1/json-schema/email-received-event.schema.json +1063 -0
- primitivedotdev-0.1.1/pyproject.toml +97 -0
- primitivedotdev-0.1.1/scripts/generate_models.py +198 -0
- primitivedotdev-0.1.1/scripts/generate_schema_module.py +26 -0
- primitivedotdev-0.1.1/src/primitive/__init__.py +157 -0
- primitivedotdev-0.1.1/src/primitive/_compat.py +9 -0
- primitivedotdev-0.1.1/src/primitive/errors.py +191 -0
- primitivedotdev-0.1.1/src/primitive/models_generated.py +874 -0
- primitivedotdev-0.1.1/src/primitive/py.typed +0 -0
- primitivedotdev-0.1.1/src/primitive/schema.py +16 -0
- primitivedotdev-0.1.1/src/primitive/schemas/email_received_event.schema.json +1063 -0
- primitivedotdev-0.1.1/src/primitive/types.py +250 -0
- primitivedotdev-0.1.1/src/primitive/validation.py +155 -0
- primitivedotdev-0.1.1/src/primitive/webhook.py +635 -0
- primitivedotdev-0.1.1/test-fixtures/auth/cases.json +192 -0
- primitivedotdev-0.1.1/test-fixtures/handle-webhook/cases.json +88 -0
- primitivedotdev-0.1.1/test-fixtures/parse-webhook-event/cases.json +86 -0
- primitivedotdev-0.1.1/test-fixtures/raw/cases.json +95 -0
- primitivedotdev-0.1.1/test-fixtures/signing/vectors.json +106 -0
- primitivedotdev-0.1.1/test-fixtures/webhook/valid-email-received.json +74 -0
- primitivedotdev-0.1.1/test-fixtures/webhook/validation-cases.json +269 -0
- primitivedotdev-0.1.1/tests/conftest.py +31 -0
- primitivedotdev-0.1.1/tests/test_auth.py +637 -0
- primitivedotdev-0.1.1/tests/test_encoding.py +38 -0
- primitivedotdev-0.1.1/tests/test_parsing.py +42 -0
- primitivedotdev-0.1.1/tests/test_shared_fixtures.py +189 -0
- primitivedotdev-0.1.1/tests/test_signing.py +585 -0
- primitivedotdev-0.1.1/tests/test_validation.py +452 -0
- primitivedotdev-0.1.1/tests/test_webhook.py +709 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
.DS_Store
|
|
2
|
+
.direnv/
|
|
3
|
+
/.envrc
|
|
4
|
+
/flake.nix
|
|
5
|
+
/flake.lock
|
|
6
|
+
node_modules/
|
|
7
|
+
sdk-node/node_modules/
|
|
8
|
+
sdk-node/dist/
|
|
9
|
+
sdk-node/*.tsbuildinfo
|
|
10
|
+
sdk-python/.venv/
|
|
11
|
+
sdk-python/dist/
|
|
12
|
+
sdk-python/.coverage
|
|
13
|
+
sdk-python/.pytest_cache/
|
|
14
|
+
sdk-python/.ruff_cache/
|
|
15
|
+
sdk-python/**/*.pyc
|
|
16
|
+
sdk-python/**/__pycache__/
|
|
17
|
+
.internal/
|
|
18
|
+
.vite/
|
|
19
|
+
dist/
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: primitivedotdev
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: Official Primitive Python SDK for webhook verification and validation
|
|
5
|
+
Project-URL: Homepage, https://primitive.dev
|
|
6
|
+
Project-URL: Repository, https://github.com/primitivedotdev/sdks
|
|
7
|
+
Project-URL: Issues, https://github.com/primitivedotdev/sdks/issues
|
|
8
|
+
Author-email: Primitive <support@primitive.dev>
|
|
9
|
+
License: MIT
|
|
10
|
+
Keywords: email,hmac,primitive,signature,webhook
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
20
|
+
Classifier: Typing :: Typed
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Requires-Dist: jsonschema<5,>=4.24.0
|
|
23
|
+
Requires-Dist: pydantic<3,>=2.11
|
|
24
|
+
Requires-Dist: typing-extensions>=4.12.0; python_version < '3.11'
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
|
|
27
|
+
# `primitivedotdev`
|
|
28
|
+
|
|
29
|
+
Official Primitive Python SDK for webhook verification and validation.
|
|
30
|
+
|
|
31
|
+
This package helps you:
|
|
32
|
+
|
|
33
|
+
- verify Primitive webhook signatures
|
|
34
|
+
- parse webhook request bodies
|
|
35
|
+
- validate webhook payloads against the canonical JSON schema
|
|
36
|
+
- work with typed `email.received` events in Python
|
|
37
|
+
|
|
38
|
+
Validated events are returned as generated Pydantic models derived from the canonical JSON schema.
|
|
39
|
+
|
|
40
|
+
## Requirements
|
|
41
|
+
|
|
42
|
+
- Python `>=3.10`
|
|
43
|
+
|
|
44
|
+
## Installation
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
pip install primitivedotdev
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Basic Usage
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
from primitive import PrimitiveWebhookError, handle_webhook
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def webhook_handler(body: bytes, headers: dict[str, str]) -> dict[str, object]:
|
|
57
|
+
try:
|
|
58
|
+
event = handle_webhook(
|
|
59
|
+
body=body,
|
|
60
|
+
headers=headers,
|
|
61
|
+
secret="whsec_...",
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
print("Email from:", event.email.headers.from_)
|
|
65
|
+
print("Subject:", event.email.headers.subject)
|
|
66
|
+
return {"received": True}
|
|
67
|
+
except PrimitiveWebhookError as error:
|
|
68
|
+
return {"error": error.code, "message": str(error)}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Core API
|
|
72
|
+
|
|
73
|
+
### Main functions
|
|
74
|
+
|
|
75
|
+
- `handle_webhook(...)`
|
|
76
|
+
- verifies the webhook signature
|
|
77
|
+
- decodes and parses the request body
|
|
78
|
+
- validates the payload
|
|
79
|
+
- returns a typed `EmailReceivedEvent`
|
|
80
|
+
- `parse_webhook_event(input)`
|
|
81
|
+
- parses a JSON payload into a known webhook event or `dict`
|
|
82
|
+
- validates known event types against the canonical schema
|
|
83
|
+
- raises `WebhookValidationError` for malformed known events
|
|
84
|
+
- `validate_email_received_event(input)`
|
|
85
|
+
- validates an `email.received` payload and returns the typed event
|
|
86
|
+
- `safe_validate_email_received_event(input)`
|
|
87
|
+
- returns a `ValidationSuccess` or `ValidationFailure`
|
|
88
|
+
- `verify_webhook_signature(...)`
|
|
89
|
+
- verifies `Primitive-Signature`
|
|
90
|
+
- `validate_email_auth(auth)`
|
|
91
|
+
- computes a verdict from SPF, DKIM, and DMARC results
|
|
92
|
+
|
|
93
|
+
### Helpful exports
|
|
94
|
+
|
|
95
|
+
- `email_received_event_json_schema`
|
|
96
|
+
- `WEBHOOK_VERSION`
|
|
97
|
+
- `PrimitiveWebhookError`
|
|
98
|
+
- `WebhookVerificationError`
|
|
99
|
+
- `WebhookPayloadError`
|
|
100
|
+
- `WebhookValidationError`
|
|
101
|
+
- `RawEmailDecodeError`
|
|
102
|
+
|
|
103
|
+
### Types and models
|
|
104
|
+
|
|
105
|
+
The package exports the main webhook models and helper types, including:
|
|
106
|
+
|
|
107
|
+
- `EmailReceivedEvent`
|
|
108
|
+
- `WebhookEvent`
|
|
109
|
+
- `UnknownEvent`
|
|
110
|
+
- `EmailAuth`
|
|
111
|
+
- `EmailAnalysis`
|
|
112
|
+
- `ParsedData`
|
|
113
|
+
- `RawContent`
|
|
114
|
+
- `WebhookAttachment`
|
|
115
|
+
|
|
116
|
+
## Parsing Events
|
|
117
|
+
|
|
118
|
+
- `parse_webhook_event(input)` strictly validates known event types such as `email.received`
|
|
119
|
+
- malformed known events raise `WebhookValidationError`
|
|
120
|
+
- unknown future event types are returned as dictionaries for forward compatibility
|
|
121
|
+
|
|
122
|
+
## JSON Schema
|
|
123
|
+
|
|
124
|
+
The webhook payload contract is defined by the canonical JSON schema in the repository and is exported by this package as `email_received_event_json_schema`.
|
|
125
|
+
|
|
126
|
+
The SDK uses that schema to generate:
|
|
127
|
+
|
|
128
|
+
- the packaged schema artifact
|
|
129
|
+
- Pydantic models
|
|
130
|
+
- runtime validation behavior
|
|
131
|
+
|
|
132
|
+
## Error Handling
|
|
133
|
+
|
|
134
|
+
All SDK-specific runtime errors extend `PrimitiveWebhookError` and include a stable error `code`.
|
|
135
|
+
|
|
136
|
+
```python
|
|
137
|
+
from primitive import PrimitiveWebhookError
|
|
138
|
+
|
|
139
|
+
try:
|
|
140
|
+
...
|
|
141
|
+
except PrimitiveWebhookError as error:
|
|
142
|
+
print(error.code, error)
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Development
|
|
146
|
+
|
|
147
|
+
From `sdks/sdk-python`:
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
uv sync --dev
|
|
151
|
+
uv run python scripts/generate_schema_module.py
|
|
152
|
+
uv run python scripts/generate_models.py
|
|
153
|
+
uv run pytest
|
|
154
|
+
uv run ruff check .
|
|
155
|
+
uv run basedpyright
|
|
156
|
+
uv run python -m build
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Or from repo root `sdks/`:
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
make python-sync
|
|
163
|
+
make python-check
|
|
164
|
+
make python-build
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## Repository Layout
|
|
168
|
+
|
|
169
|
+
```text
|
|
170
|
+
sdks/
|
|
171
|
+
json-schema/
|
|
172
|
+
email-received-event.schema.json
|
|
173
|
+
sdk-python/
|
|
174
|
+
src/primitive/
|
|
175
|
+
models_generated.py
|
|
176
|
+
schema.py
|
|
177
|
+
schemas/email_received_event.schema.json
|
|
178
|
+
validation.py
|
|
179
|
+
webhook.py
|
|
180
|
+
scripts/
|
|
181
|
+
generate_models.py
|
|
182
|
+
generate_schema_module.py
|
|
183
|
+
```
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
# `primitivedotdev`
|
|
2
|
+
|
|
3
|
+
Official Primitive Python SDK for webhook verification and validation.
|
|
4
|
+
|
|
5
|
+
This package helps you:
|
|
6
|
+
|
|
7
|
+
- verify Primitive webhook signatures
|
|
8
|
+
- parse webhook request bodies
|
|
9
|
+
- validate webhook payloads against the canonical JSON schema
|
|
10
|
+
- work with typed `email.received` events in Python
|
|
11
|
+
|
|
12
|
+
Validated events are returned as generated Pydantic models derived from the canonical JSON schema.
|
|
13
|
+
|
|
14
|
+
## Requirements
|
|
15
|
+
|
|
16
|
+
- Python `>=3.10`
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
pip install primitivedotdev
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Basic Usage
|
|
25
|
+
|
|
26
|
+
```python
|
|
27
|
+
from primitive import PrimitiveWebhookError, handle_webhook
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def webhook_handler(body: bytes, headers: dict[str, str]) -> dict[str, object]:
|
|
31
|
+
try:
|
|
32
|
+
event = handle_webhook(
|
|
33
|
+
body=body,
|
|
34
|
+
headers=headers,
|
|
35
|
+
secret="whsec_...",
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
print("Email from:", event.email.headers.from_)
|
|
39
|
+
print("Subject:", event.email.headers.subject)
|
|
40
|
+
return {"received": True}
|
|
41
|
+
except PrimitiveWebhookError as error:
|
|
42
|
+
return {"error": error.code, "message": str(error)}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Core API
|
|
46
|
+
|
|
47
|
+
### Main functions
|
|
48
|
+
|
|
49
|
+
- `handle_webhook(...)`
|
|
50
|
+
- verifies the webhook signature
|
|
51
|
+
- decodes and parses the request body
|
|
52
|
+
- validates the payload
|
|
53
|
+
- returns a typed `EmailReceivedEvent`
|
|
54
|
+
- `parse_webhook_event(input)`
|
|
55
|
+
- parses a JSON payload into a known webhook event or `dict`
|
|
56
|
+
- validates known event types against the canonical schema
|
|
57
|
+
- raises `WebhookValidationError` for malformed known events
|
|
58
|
+
- `validate_email_received_event(input)`
|
|
59
|
+
- validates an `email.received` payload and returns the typed event
|
|
60
|
+
- `safe_validate_email_received_event(input)`
|
|
61
|
+
- returns a `ValidationSuccess` or `ValidationFailure`
|
|
62
|
+
- `verify_webhook_signature(...)`
|
|
63
|
+
- verifies `Primitive-Signature`
|
|
64
|
+
- `validate_email_auth(auth)`
|
|
65
|
+
- computes a verdict from SPF, DKIM, and DMARC results
|
|
66
|
+
|
|
67
|
+
### Helpful exports
|
|
68
|
+
|
|
69
|
+
- `email_received_event_json_schema`
|
|
70
|
+
- `WEBHOOK_VERSION`
|
|
71
|
+
- `PrimitiveWebhookError`
|
|
72
|
+
- `WebhookVerificationError`
|
|
73
|
+
- `WebhookPayloadError`
|
|
74
|
+
- `WebhookValidationError`
|
|
75
|
+
- `RawEmailDecodeError`
|
|
76
|
+
|
|
77
|
+
### Types and models
|
|
78
|
+
|
|
79
|
+
The package exports the main webhook models and helper types, including:
|
|
80
|
+
|
|
81
|
+
- `EmailReceivedEvent`
|
|
82
|
+
- `WebhookEvent`
|
|
83
|
+
- `UnknownEvent`
|
|
84
|
+
- `EmailAuth`
|
|
85
|
+
- `EmailAnalysis`
|
|
86
|
+
- `ParsedData`
|
|
87
|
+
- `RawContent`
|
|
88
|
+
- `WebhookAttachment`
|
|
89
|
+
|
|
90
|
+
## Parsing Events
|
|
91
|
+
|
|
92
|
+
- `parse_webhook_event(input)` strictly validates known event types such as `email.received`
|
|
93
|
+
- malformed known events raise `WebhookValidationError`
|
|
94
|
+
- unknown future event types are returned as dictionaries for forward compatibility
|
|
95
|
+
|
|
96
|
+
## JSON Schema
|
|
97
|
+
|
|
98
|
+
The webhook payload contract is defined by the canonical JSON schema in the repository and is exported by this package as `email_received_event_json_schema`.
|
|
99
|
+
|
|
100
|
+
The SDK uses that schema to generate:
|
|
101
|
+
|
|
102
|
+
- the packaged schema artifact
|
|
103
|
+
- Pydantic models
|
|
104
|
+
- runtime validation behavior
|
|
105
|
+
|
|
106
|
+
## Error Handling
|
|
107
|
+
|
|
108
|
+
All SDK-specific runtime errors extend `PrimitiveWebhookError` and include a stable error `code`.
|
|
109
|
+
|
|
110
|
+
```python
|
|
111
|
+
from primitive import PrimitiveWebhookError
|
|
112
|
+
|
|
113
|
+
try:
|
|
114
|
+
...
|
|
115
|
+
except PrimitiveWebhookError as error:
|
|
116
|
+
print(error.code, error)
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Development
|
|
120
|
+
|
|
121
|
+
From `sdks/sdk-python`:
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
uv sync --dev
|
|
125
|
+
uv run python scripts/generate_schema_module.py
|
|
126
|
+
uv run python scripts/generate_models.py
|
|
127
|
+
uv run pytest
|
|
128
|
+
uv run ruff check .
|
|
129
|
+
uv run basedpyright
|
|
130
|
+
uv run python -m build
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Or from repo root `sdks/`:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
make python-sync
|
|
137
|
+
make python-check
|
|
138
|
+
make python-build
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Repository Layout
|
|
142
|
+
|
|
143
|
+
```text
|
|
144
|
+
sdks/
|
|
145
|
+
json-schema/
|
|
146
|
+
email-received-event.schema.json
|
|
147
|
+
sdk-python/
|
|
148
|
+
src/primitive/
|
|
149
|
+
models_generated.py
|
|
150
|
+
schema.py
|
|
151
|
+
schemas/email_received_event.schema.json
|
|
152
|
+
validation.py
|
|
153
|
+
webhook.py
|
|
154
|
+
scripts/
|
|
155
|
+
generate_models.py
|
|
156
|
+
generate_schema_module.py
|
|
157
|
+
```
|