poststack 0.4.0__py3-none-any.whl

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.
poststack/types.py ADDED
@@ -0,0 +1,511 @@
1
+ """Pydantic models mirroring the PostStack API response shapes.
2
+
3
+ Models are intentionally compact: JSON blobs (headers, metadata, properties,
4
+ trigger config, step config) use ``Dict[str, Any]`` rather than re-deriving
5
+ every possible field.
6
+
7
+ All resource methods currently return raw ``dict`` objects parsed from JSON
8
+ (for forward compatibility with API additions). These models are exported for
9
+ callers who want to validate/convert manually, e.g.::
10
+
11
+ from poststack.types import Email
12
+ raw = client.emails.get("em_123")
13
+ email = Email.model_validate(raw)
14
+ """
15
+
16
+ from __future__ import annotations
17
+
18
+ from typing import Any, Dict, List, Literal, Optional, TypedDict
19
+
20
+ from pydantic import BaseModel, ConfigDict, Field
21
+
22
+
23
+ # ---------------------------------------------------------------------------
24
+ # Literal enums (strings in the API)
25
+ # ---------------------------------------------------------------------------
26
+
27
+ EmailStatus = Literal[
28
+ "queued", "sending", "delivered", "bounced", "complained", "failed"
29
+ ]
30
+ EmailEventType = Literal[
31
+ "queued",
32
+ "sent",
33
+ "delivered",
34
+ "bounced",
35
+ "soft_bounced",
36
+ "opened",
37
+ "clicked",
38
+ "complained",
39
+ "unsubscribed",
40
+ "failed",
41
+ ]
42
+ DomainStatus = Literal["pending", "verified", "failed"]
43
+ TlsMode = Literal["opportunistic", "enforced"]
44
+ Region = Literal["eu-west-1", "us-east-1", "sa-east-1", "ap-northeast-1"]
45
+ DnsRecordType = Literal["TXT", "CNAME", "MX", "SRV"]
46
+ DnsPurpose = Literal["spf", "dkim", "dmarc", "return_path", "mx", "imap"]
47
+ BroadcastStatus = Literal["draft", "queued", "sending", "sent", "cancelled"]
48
+ SuppressionReason = Literal["hard_bounce", "complaint", "manual", "unsubscribe"]
49
+ ApiKeyPermission = Literal["full_access", "sending_access"]
50
+ ApiKeyMode = Literal["live", "test"]
51
+ MailboxStatus = Literal["active", "suspended", "deleted"]
52
+ ContactPropertyType = Literal["text", "number", "boolean", "date", "select"]
53
+ WorkflowStatus = Literal["draft", "active", "paused"]
54
+ WorkflowTriggerType = Literal["contact.created", "contact.subscribed", "manual"]
55
+ WorkflowStepType = Literal["send_email", "wait", "condition"]
56
+ WebhookDeliveryStatus = Literal["pending", "success", "failed"]
57
+ EmailValidationResult = Literal[
58
+ "deliverable", "undeliverable", "risky", "unknown"
59
+ ]
60
+ EmailValidationRisk = Literal["low", "medium", "high"]
61
+ SignupFormFieldType = Literal["email", "text", "select", "checkbox"]
62
+
63
+
64
+ class _Model(BaseModel):
65
+ """Base for all models: permissive toward new API fields."""
66
+
67
+ model_config = ConfigDict(extra="allow", populate_by_name=True)
68
+
69
+
70
+ # ---------------------------------------------------------------------------
71
+ # Shared pagination
72
+ # ---------------------------------------------------------------------------
73
+
74
+
75
+ class PaginationMeta(_Model):
76
+ page: int
77
+ per_page: int = Field(alias="perPage")
78
+ total: int
79
+ total_pages: int = Field(alias="totalPages")
80
+
81
+
82
+ # ---------------------------------------------------------------------------
83
+ # TypedDict inputs (what callers pass to send/create/update).
84
+ # Kept permissive; the server is the source of truth for validation.
85
+ # ---------------------------------------------------------------------------
86
+
87
+
88
+ class Attachment(TypedDict, total=False):
89
+ filename: str
90
+ content: str
91
+ content_type: str
92
+
93
+
94
+ class SendEmailInput(TypedDict, total=False):
95
+ from_: str
96
+ to: List[str]
97
+ cc: List[str]
98
+ bcc: List[str]
99
+ reply_to: str
100
+ subject: str
101
+ html: str
102
+ text: str
103
+ headers: Dict[str, str]
104
+ tags: List[str]
105
+ attachments: List[Attachment]
106
+ idempotency_key: str
107
+ scheduled_at: str
108
+ template_id: str
109
+ variables: Dict[str, str]
110
+
111
+
112
+ # ---------------------------------------------------------------------------
113
+ # Email
114
+ # ---------------------------------------------------------------------------
115
+
116
+
117
+ class EmailEvent(_Model):
118
+ type: EmailEventType
119
+ timestamp: str
120
+
121
+
122
+ class Email(_Model):
123
+ id: str
124
+ public_id: str = Field(alias="publicId")
125
+ from_: str = Field(alias="from")
126
+ to: List[str]
127
+ subject: str
128
+ status: EmailStatus
129
+ created_at: str = Field(alias="createdAt")
130
+ sent_at: Optional[str] = Field(default=None, alias="sentAt")
131
+ events: Optional[List[EmailEvent]] = None
132
+
133
+
134
+ class EmailInsightWarning(_Model):
135
+ type: str
136
+ message: str
137
+ severity: Literal["low", "medium", "high"]
138
+
139
+
140
+ # ---------------------------------------------------------------------------
141
+ # Domain
142
+ # ---------------------------------------------------------------------------
143
+
144
+
145
+ class DnsRecord(_Model):
146
+ type: DnsRecordType
147
+ name: str
148
+ value: str
149
+ purpose: DnsPurpose
150
+ verified: bool
151
+
152
+
153
+ class Domain(_Model):
154
+ id: int
155
+ name: str
156
+ status: DomainStatus
157
+ region: Region
158
+ dns_records: List[DnsRecord] = Field(alias="dnsRecords")
159
+ open_tracking: bool = Field(alias="openTracking")
160
+ click_tracking: bool = Field(alias="clickTracking")
161
+ catch_all: bool = Field(alias="catchAll")
162
+ tls_mode: TlsMode = Field(alias="tlsMode")
163
+ verified_at: Optional[str] = Field(default=None, alias="verifiedAt")
164
+ created_at: str = Field(alias="createdAt")
165
+
166
+
167
+ class DmarcReport(_Model):
168
+ id: int
169
+ org_name: str = Field(alias="orgName")
170
+ date_range_begin: str = Field(alias="dateRangeBegin")
171
+ date_range_end: str = Field(alias="dateRangeEnd")
172
+ total_count: int = Field(alias="totalCount")
173
+ pass_count: int = Field(alias="passCount")
174
+ fail_count: int = Field(alias="failCount")
175
+
176
+
177
+ class DmarcStats(_Model):
178
+ total_messages: int = Field(alias="totalMessages")
179
+ pass_rate: float = Field(alias="passRate")
180
+ failed_messages: int = Field(alias="failedMessages")
181
+ daily_stats: List[Dict[str, Any]] = Field(alias="dailyStats")
182
+
183
+
184
+ class DmarcSource(_Model):
185
+ source_ip: str = Field(alias="sourceIp")
186
+ org_name: Optional[str] = Field(default=None, alias="orgName")
187
+ count: int
188
+ pass_count: int = Field(alias="passCount")
189
+ fail_count: int = Field(alias="failCount")
190
+
191
+
192
+ # ---------------------------------------------------------------------------
193
+ # Contact
194
+ # ---------------------------------------------------------------------------
195
+
196
+
197
+ class Contact(_Model):
198
+ id: str
199
+ email: str
200
+ first_name: Optional[str] = Field(default=None, alias="firstName")
201
+ last_name: Optional[str] = Field(default=None, alias="lastName")
202
+ unsubscribed: bool
203
+ properties: Optional[Dict[str, Any]] = None
204
+ created_at: str = Field(alias="createdAt")
205
+
206
+
207
+ class ContactProperty(_Model):
208
+ id: int
209
+ name: str
210
+ label: str
211
+ type: ContactPropertyType
212
+ options: Optional[List[str]] = None
213
+ required: bool
214
+ created_at: str = Field(alias="createdAt")
215
+
216
+
217
+ class ImportContactsResult(_Model):
218
+ imported: int
219
+ updated: int
220
+ skipped: int
221
+ errors: List[Dict[str, str]]
222
+
223
+
224
+ # ---------------------------------------------------------------------------
225
+ # Segment
226
+ # ---------------------------------------------------------------------------
227
+
228
+
229
+ class Segment(_Model):
230
+ id: str
231
+ name: str
232
+ contact_count: int = Field(alias="contactCount")
233
+ created_at: str = Field(alias="createdAt")
234
+
235
+
236
+ class SegmentPreviewResult(_Model):
237
+ count: int
238
+ sample: List[Contact]
239
+
240
+
241
+ # ---------------------------------------------------------------------------
242
+ # Template
243
+ # ---------------------------------------------------------------------------
244
+
245
+
246
+ class Template(_Model):
247
+ id: int
248
+ public_id: str = Field(alias="publicId")
249
+ name: str
250
+ subject: str
251
+ html_body: Optional[str] = Field(default=None, alias="htmlBody")
252
+ text_body: Optional[str] = Field(default=None, alias="textBody")
253
+ variables: Optional[List[str]] = None
254
+ published: bool
255
+ version: int
256
+ created_at: str = Field(alias="createdAt")
257
+
258
+
259
+ class TemplatePreset(_Model):
260
+ id: str
261
+ name: str
262
+ description: Optional[str] = None
263
+ thumbnail: Optional[str] = None
264
+ subject: str
265
+ html: str
266
+ text: Optional[str] = None
267
+
268
+
269
+ # ---------------------------------------------------------------------------
270
+ # Webhook
271
+ # ---------------------------------------------------------------------------
272
+
273
+
274
+ class Webhook(_Model):
275
+ id: int
276
+ url: str
277
+ events: List[str]
278
+ active: bool
279
+ created_at: str = Field(alias="createdAt")
280
+
281
+
282
+ class WebhookDelivery(_Model):
283
+ id: int
284
+ webhook_id: int = Field(alias="webhookId")
285
+ event: str
286
+ status_code: Optional[int] = Field(default=None, alias="statusCode")
287
+ success: bool
288
+ attempts: int
289
+ created_at: str = Field(alias="createdAt")
290
+ next_attempt_at: Optional[str] = Field(default=None, alias="nextAttemptAt")
291
+
292
+
293
+ # ---------------------------------------------------------------------------
294
+ # Broadcast
295
+ # ---------------------------------------------------------------------------
296
+
297
+
298
+ class Broadcast(_Model):
299
+ id: int
300
+ public_id: str = Field(alias="publicId")
301
+ subject: str
302
+ status: BroadcastStatus
303
+ total_recipients: int = Field(alias="totalRecipients")
304
+ delivered_count: int = Field(alias="deliveredCount")
305
+ opened_count: int = Field(alias="openedCount")
306
+ clicked_count: int = Field(alias="clickedCount")
307
+ bounced_count: int = Field(alias="bouncedCount")
308
+ created_at: str = Field(alias="createdAt")
309
+ sent_at: Optional[str] = Field(default=None, alias="sentAt")
310
+ scheduled_at: Optional[str] = Field(default=None, alias="scheduledAt")
311
+
312
+
313
+ class BroadcastVariant(_Model):
314
+ id: int
315
+ name: str
316
+ subject: str
317
+ weight: int
318
+ delivered_count: int = Field(alias="deliveredCount")
319
+ opened_count: int = Field(alias="openedCount")
320
+ clicked_count: int = Field(alias="clickedCount")
321
+
322
+
323
+ class BroadcastVariantStats(_Model):
324
+ variants: List[BroadcastVariant]
325
+ winner: Optional[Dict[str, Any]] = None
326
+
327
+
328
+ # ---------------------------------------------------------------------------
329
+ # Suppression
330
+ # ---------------------------------------------------------------------------
331
+
332
+
333
+ class Suppression(_Model):
334
+ id: int
335
+ email: str
336
+ reason: SuppressionReason
337
+ created_at: str = Field(alias="createdAt")
338
+
339
+
340
+ # ---------------------------------------------------------------------------
341
+ # API key
342
+ # ---------------------------------------------------------------------------
343
+
344
+
345
+ class ApiKey(_Model):
346
+ id: int
347
+ name: str
348
+ key_prefix: str = Field(alias="keyPrefix")
349
+ permission: ApiKeyPermission
350
+ mode: ApiKeyMode
351
+ domain_id: Optional[int] = Field(default=None, alias="domainId")
352
+ last_used_at: Optional[str] = Field(default=None, alias="lastUsedAt")
353
+ expires_at: Optional[str] = Field(default=None, alias="expiresAt")
354
+ created_at: str = Field(alias="createdAt")
355
+
356
+
357
+ # ---------------------------------------------------------------------------
358
+ # Mailbox
359
+ # ---------------------------------------------------------------------------
360
+
361
+
362
+ class Mailbox(_Model):
363
+ id: int
364
+ team_id: int = Field(alias="teamId")
365
+ domain_id: int = Field(alias="domainId")
366
+ email_address: str = Field(alias="emailAddress")
367
+ display_name: Optional[str] = Field(default=None, alias="displayName")
368
+ quota_bytes: int = Field(alias="quotaBytes")
369
+ status: MailboxStatus
370
+ webhook_enabled: bool = Field(alias="webhookEnabled")
371
+ last_login_at: Optional[str] = Field(default=None, alias="lastLoginAt")
372
+ created_at: str = Field(alias="createdAt")
373
+ updated_at: str = Field(alias="updatedAt")
374
+
375
+
376
+ class MailboxAlias(_Model):
377
+ id: int
378
+ team_id: int = Field(alias="teamId")
379
+ domain_id: int = Field(alias="domainId")
380
+ alias_address: str = Field(alias="aliasAddress")
381
+ destination_mailbox_id: int = Field(alias="destinationMailboxId")
382
+ created_at: str = Field(alias="createdAt")
383
+
384
+
385
+ # ---------------------------------------------------------------------------
386
+ # Subscription topic
387
+ # ---------------------------------------------------------------------------
388
+
389
+
390
+ class SubscriptionTopic(_Model):
391
+ id: int
392
+ name: str
393
+ description: Optional[str] = None
394
+ created_at: str = Field(alias="createdAt")
395
+
396
+
397
+ class ContactSubscription(_Model):
398
+ topic_id: int = Field(alias="topicId")
399
+ contact_id: int = Field(alias="contactId")
400
+ subscribed_at: str = Field(alias="subscribedAt")
401
+
402
+
403
+ # ---------------------------------------------------------------------------
404
+ # Workflow
405
+ # ---------------------------------------------------------------------------
406
+
407
+
408
+ class WorkflowStep(_Model):
409
+ id: int
410
+ step_type: WorkflowStepType = Field(alias="stepType")
411
+ position: int
412
+ config: Dict[str, Any]
413
+ created_at: str = Field(alias="createdAt")
414
+
415
+
416
+ class Workflow(_Model):
417
+ id: int
418
+ public_id: str = Field(alias="publicId")
419
+ name: str
420
+ trigger_type: WorkflowTriggerType = Field(alias="triggerType")
421
+ trigger_config: Optional[Dict[str, Any]] = Field(
422
+ default=None, alias="triggerConfig"
423
+ )
424
+ status: WorkflowStatus
425
+ steps: Optional[List[WorkflowStep]] = None
426
+ created_at: str = Field(alias="createdAt")
427
+ updated_at: str = Field(alias="updatedAt")
428
+
429
+
430
+ # ---------------------------------------------------------------------------
431
+ # Signup form
432
+ # ---------------------------------------------------------------------------
433
+
434
+
435
+ class SignupFormField(_Model):
436
+ name: str
437
+ type: SignupFormFieldType
438
+ label: str
439
+ required: Optional[bool] = None
440
+ options: Optional[List[str]] = None
441
+
442
+
443
+ class SignupForm(_Model):
444
+ id: int
445
+ public_id: str = Field(alias="publicId")
446
+ name: str
447
+ segment_id: Optional[int] = Field(default=None, alias="segmentId")
448
+ topic_id: Optional[int] = Field(default=None, alias="topicId")
449
+ fields: List[SignupFormField]
450
+ success_message: Optional[str] = Field(
451
+ default=None, alias="successMessage"
452
+ )
453
+ redirect_url: Optional[str] = Field(default=None, alias="redirectUrl")
454
+ active: bool
455
+ submission_count: int = Field(alias="submissionCount")
456
+ created_at: str = Field(alias="createdAt")
457
+ updated_at: str = Field(alias="updatedAt")
458
+
459
+
460
+ # ---------------------------------------------------------------------------
461
+ # Email validation
462
+ # ---------------------------------------------------------------------------
463
+
464
+
465
+ class EmailValidation(_Model):
466
+ email: str
467
+ result: EmailValidationResult
468
+ syntax_valid: bool = Field(alias="syntaxValid")
469
+ mx_valid: bool = Field(alias="mxValid")
470
+ is_disposable: bool = Field(alias="isDisposable")
471
+ is_role: bool = Field(alias="isRole")
472
+ is_free: bool = Field(alias="isFree")
473
+ risk: EmailValidationRisk
474
+
475
+
476
+ __all__ = [
477
+ "PaginationMeta",
478
+ "Attachment",
479
+ "SendEmailInput",
480
+ "EmailEvent",
481
+ "Email",
482
+ "EmailInsightWarning",
483
+ "DnsRecord",
484
+ "Domain",
485
+ "DmarcReport",
486
+ "DmarcStats",
487
+ "DmarcSource",
488
+ "Contact",
489
+ "ContactProperty",
490
+ "ImportContactsResult",
491
+ "Segment",
492
+ "SegmentPreviewResult",
493
+ "Template",
494
+ "TemplatePreset",
495
+ "Webhook",
496
+ "WebhookDelivery",
497
+ "Broadcast",
498
+ "BroadcastVariant",
499
+ "BroadcastVariantStats",
500
+ "Suppression",
501
+ "ApiKey",
502
+ "Mailbox",
503
+ "MailboxAlias",
504
+ "SubscriptionTopic",
505
+ "ContactSubscription",
506
+ "WorkflowStep",
507
+ "Workflow",
508
+ "SignupFormField",
509
+ "SignupForm",
510
+ "EmailValidation",
511
+ ]
@@ -0,0 +1,155 @@
1
+ Metadata-Version: 2.4
2
+ Name: poststack
3
+ Version: 0.4.0
4
+ Summary: Official Python SDK for the PostStack Email API
5
+ Project-URL: Homepage, https://poststack.dev
6
+ Project-URL: Documentation, https://poststack.dev/docs
7
+ Project-URL: Repository, https://github.com/getpoststack/python-sdk
8
+ Project-URL: Issues, https://github.com/getpoststack/python-sdk/issues
9
+ Author: PostStack
10
+ License: MIT
11
+ License-File: LICENSE
12
+ Keywords: api,email,poststack,smtp,transactional
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Communications :: Email
22
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
23
+ Requires-Python: >=3.10
24
+ Requires-Dist: httpx>=0.25.0
25
+ Requires-Dist: pydantic>=2.0.0
26
+ Provides-Extra: dev
27
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
28
+ Requires-Dist: pytest>=7.0.0; extra == 'dev'
29
+ Requires-Dist: respx>=0.20.0; extra == 'dev'
30
+ Description-Content-Type: text/markdown
31
+
32
+ # PostStack Python SDK
33
+
34
+ Official Python SDK for the [PostStack](https://poststack.dev) Email API —
35
+ an [EU-hosted, GDPR-compliant](https://poststack.dev/security)
36
+ [email API for Python](https://poststack.dev) with sync and async clients,
37
+ full type hints, and drop-in compatibility with Django, FastAPI, Flask,
38
+ and Starlette. Up to 75% cheaper than Resend, SendGrid, and Postmark.
39
+
40
+ Docs: [poststack.dev/docs/sdk](https://poststack.dev/docs/sdk).
41
+
42
+ ## Installation
43
+
44
+ ```bash
45
+ pip install poststack
46
+ ```
47
+
48
+ Requires Python 3.10+.
49
+
50
+ ## Quick start
51
+
52
+ ```python
53
+ from poststack import PostStack
54
+
55
+ client = PostStack(api_key="sk_live_...")
56
+
57
+ result = client.emails.send({
58
+ "from": "hello@example.com",
59
+ "to": ["user@example.com"],
60
+ "subject": "Hello from PostStack",
61
+ "html": "<p>Welcome!</p>",
62
+ })
63
+
64
+ print(result["id"])
65
+ ```
66
+
67
+ ## Async usage
68
+
69
+ ```python
70
+ import asyncio
71
+ from poststack import AsyncPostStack
72
+
73
+ async def main():
74
+ client = AsyncPostStack(api_key="sk_live_...")
75
+ try:
76
+ result = await client.emails.send({
77
+ "from": "hello@example.com",
78
+ "to": ["user@example.com"],
79
+ "subject": "Hello from PostStack",
80
+ "html": "<p>Welcome!</p>",
81
+ })
82
+ print(result["id"])
83
+ finally:
84
+ await client.aclose()
85
+
86
+ asyncio.run(main())
87
+ ```
88
+
89
+ Or use it as an async context manager:
90
+
91
+ ```python
92
+ async with AsyncPostStack(api_key="sk_live_...") as client:
93
+ result = await client.emails.send({...})
94
+ ```
95
+
96
+ ## Error handling
97
+
98
+ Any non-2xx response raises `PostStackError`:
99
+
100
+ ```python
101
+ from poststack import PostStack, PostStackError
102
+
103
+ client = PostStack(api_key="sk_live_...")
104
+
105
+ try:
106
+ client.emails.send({"from": "x@y.com", "to": ["z@w.com"], "subject": "hi"})
107
+ except PostStackError as e:
108
+ print(e.status_code, e.error, e.request_id)
109
+ ```
110
+
111
+ ## Configuration
112
+
113
+ ```python
114
+ client = PostStack(
115
+ api_key="sk_live_...",
116
+ base_url="https://api.poststack.dev", # default
117
+ timeout=30.0, # default (seconds)
118
+ )
119
+ ```
120
+
121
+ Override timeout per call:
122
+
123
+ ```python
124
+ client.emails.send({...}, timeout=60.0)
125
+ ```
126
+
127
+ ## Resources
128
+
129
+ - `client.emails` — send, get, list, cancel, reschedule, batch, events, insights
130
+ - `client.domains` — create, list, get, verify, update, delete, DMARC
131
+ - `client.contacts` — CRUD, import, export, unsubscribe
132
+ - `client.contact_properties` — custom properties
133
+ - `client.segments` — create, list, get, update, delete, contacts, preview
134
+ - `client.templates` — CRUD, publish, duplicate, presets
135
+ - `client.webhooks` — CRUD, test, deliveries, replay
136
+ - `client.broadcasts` — CRUD, send, test, variants
137
+ - `client.suppressions` — list, add, remove
138
+ - `client.api_keys` — CRUD
139
+ - `client.mailboxes` — CRUD, aliases, password
140
+ - `client.subscription_topics` — topics + contact subscriptions
141
+ - `client.workflows` — CRUD, steps, activate, pause, trigger
142
+ - `client.signup_forms` — CRUD, submit
143
+ - `client.email_validations` — validate, validate_batch
144
+
145
+ ## Links
146
+
147
+ - [PostStack — EU-hosted email API](https://poststack.dev)
148
+ - [API documentation](https://poststack.dev/docs)
149
+ - [Pricing](https://poststack.dev/pricing) · [Compare providers](https://poststack.dev/pricing/compare)
150
+ - [Migrate from Resend](https://poststack.dev/migrate/resend) · [from SendGrid](https://poststack.dev/migrate/sendgrid) · [from Postmark](https://poststack.dev/migrate/postmark)
151
+ - [Status](https://poststack.dev/status) · [Security](https://poststack.dev/security) · [DPA](https://poststack.dev/dpa)
152
+
153
+ ## License
154
+
155
+ MIT — see [LICENSE](./LICENSE).
@@ -0,0 +1,24 @@
1
+ poststack/__init__.py,sha256=_ehy6cQ1ozYlDUh8iyZhLHFJSAvSX8sRSS2tQopjMNw,4857
2
+ poststack/_client.py,sha256=82_v2DbcfNEmUVfrjl33NdYq4_uGdcfJbY3QPimfzNU,9860
3
+ poststack/_errors.py,sha256=X8qQ4xaIsetDB8uDgxVEPRBOAhOSJrR5rmFs_UPBacI,894
4
+ poststack/types.py,sha256=ecBtZnAxkbgtPZ1vq2nRnd-RrsYAJKoFfSwhWFKwDqw,15019
5
+ poststack/resources/__init__.py,sha256=myTAQKQ29s6hVUutb1H8Z-SHgLV1MQQizen3XOA53dQ,2023
6
+ poststack/resources/api_keys.py,sha256=a3t1HNezQyXcaL02DAIFaFQBC_90eROmgcaUJJcSKkI,2000
7
+ poststack/resources/broadcasts.py,sha256=JZ8HAPG9rYG_euXpBN6lZ1eSZ5RE0_gdRmkNK9_uT6A,4747
8
+ poststack/resources/contact_properties.py,sha256=HmYh3OqMiESQJMiFxwKbyAR35oWgHdia_UjziDoq7BI,2197
9
+ poststack/resources/contacts.py,sha256=FDlNi36_3cN9uXKG5I1KWMNlwIl92FE1Qfof4BcYIuQ,3988
10
+ poststack/resources/domains.py,sha256=HAa15Oy3VBN5K_7MRe0XLapKBgu6T7OjMx7vyTT-YZI,5848
11
+ poststack/resources/email_validations.py,sha256=K-Vc3Ky1vNkjcOL9599rRkj5teW02ZuH8IBog4mOXbI,1498
12
+ poststack/resources/emails.py,sha256=53eQbSYyMnp5qWaIVv5TwB8CiS4RHGyw1TjuAqcqQAo,3993
13
+ poststack/resources/mailboxes.py,sha256=B2Nh60duCI5juwNAzpPHTb5x0D-u0OKhW1pd8qcFLD0,4570
14
+ poststack/resources/segments.py,sha256=CarkZsrOv1-DmzcNvggXPKOG5Id9mdOL8vDQ47QE7z4,4451
15
+ poststack/resources/signup_forms.py,sha256=7LJpORwi6Ihno5B-wuOXhA8-XzycqUnZeUW5YrIXXb4,3461
16
+ poststack/resources/subscription_topics.py,sha256=VOW4oaI0LAhWSgsZ3KFvtzuPfLnpxFOny36TljcEGTY,3589
17
+ poststack/resources/suppressions.py,sha256=P6sp1YXXLjIw4n5DAlDo23fSJKC4mROSUSuyk3ZJcq8,1835
18
+ poststack/resources/templates.py,sha256=Lc2-2UFGNYXO8WBnOKaiB7s-Q0-wBjhbGP8Ty1h7elo,4953
19
+ poststack/resources/webhooks.py,sha256=4X8u7h-X18HAUcGSgEMZ9FwuXenjYAXN4aEOUzDc3GE,4044
20
+ poststack/resources/workflows.py,sha256=kpqAOjDjRs-Xqxor744f4Hr6QRLtNalHmHuoKJDSQas,5397
21
+ poststack-0.4.0.dist-info/METADATA,sha256=0l7BeA7nLr3axFChqjpy9dC5-mquWRHNug6FU6Wmh7Y,4771
22
+ poststack-0.4.0.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
23
+ poststack-0.4.0.dist-info/licenses/LICENSE,sha256=xQFLbiPx_5D3Zh06D12XhGi_DHvRNsJMz2z7_JHGLO0,1074
24
+ poststack-0.4.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.29.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any