emailr 1.0.0__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.
emailr-1.0.0/PKG-INFO ADDED
@@ -0,0 +1,315 @@
1
+ Metadata-Version: 2.4
2
+ Name: emailr
3
+ Version: 1.0.0
4
+ Summary: Official Emailr API SDK for Python
5
+ Author-email: Emailr <support@emailr.dev>
6
+ License: MIT
7
+ Project-URL: Homepage, https://emailr.dev
8
+ Project-URL: Documentation, https://docs.emailr.dev
9
+ Project-URL: Repository, https://github.com/emailr-dev/emailr
10
+ Project-URL: Changelog, https://github.com/emailr-dev/emailr/blob/main/CHANGELOG.md
11
+ Keywords: email,api,sdk,emailr,transactional-email
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.8
18
+ Classifier: Programming Language :: Python :: 3.9
19
+ Classifier: Programming Language :: Python :: 3.10
20
+ Classifier: Programming Language :: Python :: 3.11
21
+ Classifier: Programming Language :: Python :: 3.12
22
+ Classifier: Topic :: Communications :: Email
23
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
24
+ Classifier: Typing :: Typed
25
+ Requires-Python: >=3.8
26
+ Description-Content-Type: text/markdown
27
+ Requires-Dist: httpx>=0.24.0
28
+ Provides-Extra: dev
29
+ Requires-Dist: pytest>=7.0; extra == "dev"
30
+ Requires-Dist: pytest-asyncio>=0.21; extra == "dev"
31
+ Requires-Dist: pytest-httpx>=0.21; extra == "dev"
32
+ Requires-Dist: mypy>=1.0; extra == "dev"
33
+ Requires-Dist: ruff>=0.1.0; extra == "dev"
34
+
35
+ # Emailr Python SDK
36
+
37
+ Official Python SDK for the Emailr email API. Supports both synchronous and asynchronous operations.
38
+
39
+ ## Installation
40
+
41
+ ```bash
42
+ pip install emailr
43
+ ```
44
+
45
+ ## Quick Start
46
+
47
+ ### Synchronous Usage
48
+
49
+ ```python
50
+ from emailr import Emailr
51
+
52
+ client = Emailr(api_key="your-api-key")
53
+
54
+ # Send an email
55
+ email = client.emails.send(
56
+ from_address="you@example.com",
57
+ to=["user@example.com"],
58
+ subject="Hello from Emailr!",
59
+ html="<p>Welcome to Emailr!</p>"
60
+ )
61
+
62
+ print(f"Email sent: {email.id}")
63
+ ```
64
+
65
+ ### Async Usage
66
+
67
+ ```python
68
+ import asyncio
69
+ from emailr import AsyncEmailr
70
+
71
+ async def main():
72
+ client = AsyncEmailr(api_key="your-api-key")
73
+
74
+ # Send an email
75
+ email = await client.emails.send(
76
+ from_address="you@example.com",
77
+ to=["user@example.com"],
78
+ subject="Hello from Emailr!",
79
+ html="<p>Welcome to Emailr!</p>"
80
+ )
81
+
82
+ print(f"Email sent: {email.id}")
83
+
84
+ asyncio.run(main())
85
+ ```
86
+
87
+ ## Features
88
+
89
+ - **Sync and Async**: Full support for both synchronous and asynchronous operations
90
+ - **Type Hints**: Complete type annotations for better IDE support
91
+ - **Dataclasses**: All response types are Python dataclasses
92
+ - **Error Handling**: Structured exceptions for API errors
93
+
94
+ ## Resources
95
+
96
+ ### Emails
97
+
98
+ ```python
99
+ # Send an email
100
+ email = client.emails.send(
101
+ from_address="you@example.com",
102
+ to=["user@example.com"],
103
+ subject="Hello!",
104
+ html="<p>Content</p>",
105
+ text="Content", # Optional plain text
106
+ reply_to="reply@example.com", # Optional
107
+ tags=["welcome", "onboarding"], # Optional
108
+ )
109
+
110
+ # Get an email by ID
111
+ email = client.emails.get("email_123")
112
+
113
+ # List emails
114
+ emails = client.emails.list(limit=10)
115
+ ```
116
+
117
+ ### Contacts
118
+
119
+ ```python
120
+ # Create a contact
121
+ contact = client.contacts.create(
122
+ email="user@example.com",
123
+ first_name="John",
124
+ last_name="Doe",
125
+ metadata={"plan": "pro"}
126
+ )
127
+
128
+ # Get a contact
129
+ contact = client.contacts.get("contact_123")
130
+
131
+ # Update a contact
132
+ contact = client.contacts.update("contact_123", first_name="Jane")
133
+
134
+ # List contacts
135
+ contacts = client.contacts.list(limit=50)
136
+
137
+ # Delete a contact
138
+ client.contacts.delete("contact_123")
139
+ ```
140
+
141
+ ### Templates
142
+
143
+ ```python
144
+ # Create a template
145
+ template = client.templates.create(
146
+ name="Welcome Email",
147
+ subject="Welcome, {{name}}!",
148
+ html="<p>Hello {{name}}, welcome to our service!</p>"
149
+ )
150
+
151
+ # Get a template
152
+ template = client.templates.get("template_123")
153
+
154
+ # Update a template
155
+ template = client.templates.update("template_123", subject="New Subject")
156
+
157
+ # List templates
158
+ templates = client.templates.list()
159
+
160
+ # Delete a template
161
+ client.templates.delete("template_123")
162
+ ```
163
+
164
+ ### Domains
165
+
166
+ ```python
167
+ # Add a domain
168
+ domain = client.domains.add(domain="example.com")
169
+
170
+ # Get DNS records to configure
171
+ print(domain.dns_records)
172
+
173
+ # Verify domain
174
+ result = client.domains.verify("domain_123")
175
+
176
+ # Check DNS status
177
+ dns_status = client.domains.check_dns("domain_123")
178
+
179
+ # List domains
180
+ domains = client.domains.list()
181
+
182
+ # Delete a domain
183
+ client.domains.delete("domain_123")
184
+ ```
185
+
186
+ ### Webhooks
187
+
188
+ ```python
189
+ # Create a webhook
190
+ webhook = client.webhooks.create(
191
+ url="https://example.com/webhook",
192
+ events=["email.delivered", "email.bounced", "email.complained"]
193
+ )
194
+
195
+ # Get a webhook
196
+ webhook = client.webhooks.get("webhook_123")
197
+
198
+ # Update a webhook
199
+ webhook = client.webhooks.update("webhook_123", events=["email.delivered"])
200
+
201
+ # List webhooks
202
+ webhooks = client.webhooks.list()
203
+
204
+ # Delete a webhook
205
+ client.webhooks.delete("webhook_123")
206
+ ```
207
+
208
+ ### Broadcasts
209
+
210
+ ```python
211
+ # Create a broadcast
212
+ broadcast = client.broadcasts.create(
213
+ name="Newsletter",
214
+ subject="Weekly Update",
215
+ html="<p>This week's news...</p>",
216
+ segment_id="segment_123"
217
+ )
218
+
219
+ # Send a broadcast
220
+ client.broadcasts.send("broadcast_123")
221
+
222
+ # Schedule a broadcast
223
+ client.broadcasts.schedule("broadcast_123", scheduled_at="2024-01-15T10:00:00Z")
224
+
225
+ # Get broadcast stats
226
+ stats = client.broadcasts.get_stats("broadcast_123")
227
+
228
+ # List broadcasts
229
+ broadcasts = client.broadcasts.list()
230
+ ```
231
+
232
+ ### Segments
233
+
234
+ ```python
235
+ # Create a segment
236
+ segment = client.segments.create(
237
+ name="Active Users",
238
+ conditions=[
239
+ {"field": "metadata.plan", "operator": "equals", "value": "pro"}
240
+ ]
241
+ )
242
+
243
+ # Get a segment
244
+ segment = client.segments.get("segment_123")
245
+
246
+ # Update a segment
247
+ segment = client.segments.update("segment_123", name="Premium Users")
248
+
249
+ # List segments
250
+ segments = client.segments.list()
251
+
252
+ # Delete a segment
253
+ client.segments.delete("segment_123")
254
+ ```
255
+
256
+ ## Error Handling
257
+
258
+ ```python
259
+ from emailr import Emailr
260
+ from emailr.errors import EmailrError, ValidationError, AuthenticationError, NotFoundError
261
+
262
+ client = Emailr(api_key="your-api-key")
263
+
264
+ try:
265
+ email = client.emails.send(
266
+ from_address="you@example.com",
267
+ to=["user@example.com"],
268
+ subject="Hello!",
269
+ html="<p>Content</p>"
270
+ )
271
+ except ValidationError as e:
272
+ print(f"Validation error: {e.message}")
273
+ print(f"Details: {e.errors}")
274
+ except AuthenticationError as e:
275
+ print(f"Authentication failed: {e.message}")
276
+ except NotFoundError as e:
277
+ print(f"Resource not found: {e.message}")
278
+ except EmailrError as e:
279
+ print(f"API error: {e.message} (status: {e.status_code})")
280
+ ```
281
+
282
+ ## Configuration
283
+
284
+ ### Environment Variables
285
+
286
+ ```bash
287
+ export EMAILR_API_KEY=your-api-key
288
+ export EMAILR_BASE_URL=https://api.emailr.com # Optional
289
+ ```
290
+
291
+ ```python
292
+ import os
293
+ from emailr import Emailr
294
+
295
+ # Will use EMAILR_API_KEY from environment
296
+ client = Emailr(api_key=os.environ.get("EMAILR_API_KEY"))
297
+ ```
298
+
299
+ ### Custom Base URL
300
+
301
+ ```python
302
+ client = Emailr(
303
+ api_key="your-api-key",
304
+ base_url="https://api.custom-domain.com"
305
+ )
306
+ ```
307
+
308
+ ## Requirements
309
+
310
+ - Python 3.8+
311
+ - httpx
312
+
313
+ ## License
314
+
315
+ MIT
emailr-1.0.0/README.md ADDED
@@ -0,0 +1,281 @@
1
+ # Emailr Python SDK
2
+
3
+ Official Python SDK for the Emailr email API. Supports both synchronous and asynchronous operations.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install emailr
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ### Synchronous Usage
14
+
15
+ ```python
16
+ from emailr import Emailr
17
+
18
+ client = Emailr(api_key="your-api-key")
19
+
20
+ # Send an email
21
+ email = client.emails.send(
22
+ from_address="you@example.com",
23
+ to=["user@example.com"],
24
+ subject="Hello from Emailr!",
25
+ html="<p>Welcome to Emailr!</p>"
26
+ )
27
+
28
+ print(f"Email sent: {email.id}")
29
+ ```
30
+
31
+ ### Async Usage
32
+
33
+ ```python
34
+ import asyncio
35
+ from emailr import AsyncEmailr
36
+
37
+ async def main():
38
+ client = AsyncEmailr(api_key="your-api-key")
39
+
40
+ # Send an email
41
+ email = await client.emails.send(
42
+ from_address="you@example.com",
43
+ to=["user@example.com"],
44
+ subject="Hello from Emailr!",
45
+ html="<p>Welcome to Emailr!</p>"
46
+ )
47
+
48
+ print(f"Email sent: {email.id}")
49
+
50
+ asyncio.run(main())
51
+ ```
52
+
53
+ ## Features
54
+
55
+ - **Sync and Async**: Full support for both synchronous and asynchronous operations
56
+ - **Type Hints**: Complete type annotations for better IDE support
57
+ - **Dataclasses**: All response types are Python dataclasses
58
+ - **Error Handling**: Structured exceptions for API errors
59
+
60
+ ## Resources
61
+
62
+ ### Emails
63
+
64
+ ```python
65
+ # Send an email
66
+ email = client.emails.send(
67
+ from_address="you@example.com",
68
+ to=["user@example.com"],
69
+ subject="Hello!",
70
+ html="<p>Content</p>",
71
+ text="Content", # Optional plain text
72
+ reply_to="reply@example.com", # Optional
73
+ tags=["welcome", "onboarding"], # Optional
74
+ )
75
+
76
+ # Get an email by ID
77
+ email = client.emails.get("email_123")
78
+
79
+ # List emails
80
+ emails = client.emails.list(limit=10)
81
+ ```
82
+
83
+ ### Contacts
84
+
85
+ ```python
86
+ # Create a contact
87
+ contact = client.contacts.create(
88
+ email="user@example.com",
89
+ first_name="John",
90
+ last_name="Doe",
91
+ metadata={"plan": "pro"}
92
+ )
93
+
94
+ # Get a contact
95
+ contact = client.contacts.get("contact_123")
96
+
97
+ # Update a contact
98
+ contact = client.contacts.update("contact_123", first_name="Jane")
99
+
100
+ # List contacts
101
+ contacts = client.contacts.list(limit=50)
102
+
103
+ # Delete a contact
104
+ client.contacts.delete("contact_123")
105
+ ```
106
+
107
+ ### Templates
108
+
109
+ ```python
110
+ # Create a template
111
+ template = client.templates.create(
112
+ name="Welcome Email",
113
+ subject="Welcome, {{name}}!",
114
+ html="<p>Hello {{name}}, welcome to our service!</p>"
115
+ )
116
+
117
+ # Get a template
118
+ template = client.templates.get("template_123")
119
+
120
+ # Update a template
121
+ template = client.templates.update("template_123", subject="New Subject")
122
+
123
+ # List templates
124
+ templates = client.templates.list()
125
+
126
+ # Delete a template
127
+ client.templates.delete("template_123")
128
+ ```
129
+
130
+ ### Domains
131
+
132
+ ```python
133
+ # Add a domain
134
+ domain = client.domains.add(domain="example.com")
135
+
136
+ # Get DNS records to configure
137
+ print(domain.dns_records)
138
+
139
+ # Verify domain
140
+ result = client.domains.verify("domain_123")
141
+
142
+ # Check DNS status
143
+ dns_status = client.domains.check_dns("domain_123")
144
+
145
+ # List domains
146
+ domains = client.domains.list()
147
+
148
+ # Delete a domain
149
+ client.domains.delete("domain_123")
150
+ ```
151
+
152
+ ### Webhooks
153
+
154
+ ```python
155
+ # Create a webhook
156
+ webhook = client.webhooks.create(
157
+ url="https://example.com/webhook",
158
+ events=["email.delivered", "email.bounced", "email.complained"]
159
+ )
160
+
161
+ # Get a webhook
162
+ webhook = client.webhooks.get("webhook_123")
163
+
164
+ # Update a webhook
165
+ webhook = client.webhooks.update("webhook_123", events=["email.delivered"])
166
+
167
+ # List webhooks
168
+ webhooks = client.webhooks.list()
169
+
170
+ # Delete a webhook
171
+ client.webhooks.delete("webhook_123")
172
+ ```
173
+
174
+ ### Broadcasts
175
+
176
+ ```python
177
+ # Create a broadcast
178
+ broadcast = client.broadcasts.create(
179
+ name="Newsletter",
180
+ subject="Weekly Update",
181
+ html="<p>This week's news...</p>",
182
+ segment_id="segment_123"
183
+ )
184
+
185
+ # Send a broadcast
186
+ client.broadcasts.send("broadcast_123")
187
+
188
+ # Schedule a broadcast
189
+ client.broadcasts.schedule("broadcast_123", scheduled_at="2024-01-15T10:00:00Z")
190
+
191
+ # Get broadcast stats
192
+ stats = client.broadcasts.get_stats("broadcast_123")
193
+
194
+ # List broadcasts
195
+ broadcasts = client.broadcasts.list()
196
+ ```
197
+
198
+ ### Segments
199
+
200
+ ```python
201
+ # Create a segment
202
+ segment = client.segments.create(
203
+ name="Active Users",
204
+ conditions=[
205
+ {"field": "metadata.plan", "operator": "equals", "value": "pro"}
206
+ ]
207
+ )
208
+
209
+ # Get a segment
210
+ segment = client.segments.get("segment_123")
211
+
212
+ # Update a segment
213
+ segment = client.segments.update("segment_123", name="Premium Users")
214
+
215
+ # List segments
216
+ segments = client.segments.list()
217
+
218
+ # Delete a segment
219
+ client.segments.delete("segment_123")
220
+ ```
221
+
222
+ ## Error Handling
223
+
224
+ ```python
225
+ from emailr import Emailr
226
+ from emailr.errors import EmailrError, ValidationError, AuthenticationError, NotFoundError
227
+
228
+ client = Emailr(api_key="your-api-key")
229
+
230
+ try:
231
+ email = client.emails.send(
232
+ from_address="you@example.com",
233
+ to=["user@example.com"],
234
+ subject="Hello!",
235
+ html="<p>Content</p>"
236
+ )
237
+ except ValidationError as e:
238
+ print(f"Validation error: {e.message}")
239
+ print(f"Details: {e.errors}")
240
+ except AuthenticationError as e:
241
+ print(f"Authentication failed: {e.message}")
242
+ except NotFoundError as e:
243
+ print(f"Resource not found: {e.message}")
244
+ except EmailrError as e:
245
+ print(f"API error: {e.message} (status: {e.status_code})")
246
+ ```
247
+
248
+ ## Configuration
249
+
250
+ ### Environment Variables
251
+
252
+ ```bash
253
+ export EMAILR_API_KEY=your-api-key
254
+ export EMAILR_BASE_URL=https://api.emailr.com # Optional
255
+ ```
256
+
257
+ ```python
258
+ import os
259
+ from emailr import Emailr
260
+
261
+ # Will use EMAILR_API_KEY from environment
262
+ client = Emailr(api_key=os.environ.get("EMAILR_API_KEY"))
263
+ ```
264
+
265
+ ### Custom Base URL
266
+
267
+ ```python
268
+ client = Emailr(
269
+ api_key="your-api-key",
270
+ base_url="https://api.custom-domain.com"
271
+ )
272
+ ```
273
+
274
+ ## Requirements
275
+
276
+ - Python 3.8+
277
+ - httpx
278
+
279
+ ## License
280
+
281
+ MIT