kirimel-python 0.1.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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 KiriMel
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,504 @@
1
+ Metadata-Version: 2.4
2
+ Name: kirimel-python
3
+ Version: 0.1.0
4
+ Summary: Official KiriMel Python SDK
5
+ Author-email: KiriMel <support@kirimel.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/kirimel/kirimel-python-sdk
8
+ Project-URL: Documentation, https://docs.kirimel.com
9
+ Project-URL: Repository, https://github.com/kirimel/kirimel-python-sdk
10
+ Project-URL: Issues, https://github.com/kirimel/kirimel-python-sdk/issues
11
+ Keywords: kirimel,email,marketing,sdk,api
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.8
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Requires-Python: >=3.8
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Requires-Dist: requests>=2.28.0
24
+ Provides-Extra: dev
25
+ Requires-Dist: pytest>=7.0; extra == "dev"
26
+ Requires-Dist: pytest-cov>=4.0; extra == "dev"
27
+ Requires-Dist: black>=23.0; extra == "dev"
28
+ Requires-Dist: mypy>=1.0; extra == "dev"
29
+ Dynamic: license-file
30
+
31
+ # KiriMel Python SDK
32
+
33
+ Official Python SDK for KiriMel Email Marketing API.
34
+
35
+ ## Installation
36
+
37
+ ```bash
38
+ pip install kirimel-python
39
+ ```
40
+
41
+ ## Quick Start
42
+
43
+ ```python
44
+ import kirimel
45
+
46
+ # Initialize the client
47
+ client = kirimel.KiriMel(
48
+ api_key='sk_test_xxx', # Or set KIRIMEL_API_KEY env variable
49
+ base_url='https://api.kirimel.com/v2',
50
+ timeout=30,
51
+ retries=3
52
+ )
53
+
54
+ # List campaigns
55
+ campaigns = client.campaigns.list(status='sent', limit=20)
56
+
57
+ # Create a campaign
58
+ campaign = client.campaigns.create({
59
+ 'name': 'Welcome Email',
60
+ 'subject': 'Welcome to KiriMel!',
61
+ 'list_id': 123,
62
+ 'template_id': 456
63
+ })
64
+
65
+ # Get campaign statistics
66
+ stats = client.campaigns.stats(campaign['id'])
67
+ ```
68
+
69
+ ## Authentication
70
+
71
+ The SDK supports two authentication methods:
72
+
73
+ ```python
74
+ # Method 1: API Key (recommended)
75
+ client = kirimel.KiriMel(api_key='sk_test_xxx')
76
+
77
+ # Method 2: Environment variable
78
+ # Set KIRIMEL_API_KEY=sk_test_xxx in your environment
79
+ client = kirimel.KiriMel()
80
+ ```
81
+
82
+ ## Resources
83
+
84
+ ### Campaigns
85
+
86
+ ```python
87
+ # List campaigns
88
+ campaigns = client.campaigns.list(limit=20, status='sent')
89
+
90
+ # Get recent campaigns
91
+ recent = client.campaigns.recent()
92
+
93
+ # Get single campaign
94
+ campaign = client.campaigns.get(id)
95
+
96
+ # Create campaign
97
+ campaign = client.campaigns.create({
98
+ 'name': 'Summer Sale',
99
+ 'subject': '50% Off Everything!',
100
+ 'list_id': 123,
101
+ 'template_id': 456
102
+ })
103
+
104
+ # Update campaign
105
+ client.campaigns.update(id, {'subject': 'New Subject'})
106
+
107
+ # Delete campaign
108
+ client.campaigns.delete(id)
109
+
110
+ # Duplicate campaign
111
+ duplicate = client.campaigns.duplicate(id)
112
+
113
+ # Schedule campaign
114
+ client.campaigns.schedule(id, '2024-06-01 10:00:00')
115
+
116
+ # Pause campaign
117
+ client.campaigns.pause(id)
118
+
119
+ # Resume campaign
120
+ client.campaigns.resume(id)
121
+
122
+ # Get campaign statistics
123
+ stats = client.campaigns.stats(id)
124
+ ```
125
+
126
+ ### Subscribers
127
+
128
+ ```python
129
+ # List subscribers for a list
130
+ subscribers = client.subscribers.list(list_id, limit=50)
131
+
132
+ # Get single subscriber
133
+ subscriber = client.subscribers.get(id)
134
+
135
+ # Add subscriber to a list
136
+ subscriber = client.subscribers.create(list_id, {
137
+ 'email': 'user@example.com',
138
+ 'first_name': 'John',
139
+ 'last_name': 'Doe'
140
+ })
141
+
142
+ # Update subscriber
143
+ client.subscribers.update(id, {'first_name': 'Jane'})
144
+
145
+ # Delete subscriber
146
+ client.subscribers.delete(id)
147
+
148
+ # Unsubscribe subscriber
149
+ client.subscribers.unsubscribe(id)
150
+
151
+ # Bulk unsubscribe
152
+ client.subscribers.bulk_unsubscribe([id1, id2, id3])
153
+
154
+ # Bulk delete
155
+ client.subscribers.bulk_delete([id1, id2, id3])
156
+
157
+ # Get subscriber activity
158
+ activity = client.subscribers.activity(id)
159
+
160
+ # Get subscriber statistics
161
+ stats = client.subscribers.stats(id)
162
+
163
+ # Toggle VIP status
164
+ client.subscribers.toggle_vip(id)
165
+
166
+ # Search subscribers
167
+ results = client.subscribers.search('john@example.com')
168
+
169
+ # Add tag
170
+ client.subscribers.add_tag(id, 'premium-customer')
171
+
172
+ # Remove tag
173
+ client.subscribers.remove_tag(id, 'premium-customer')
174
+
175
+ # Import subscribers
176
+ result = client.subscribers.import_subscribers(list_id, {
177
+ 'subscribers': [
178
+ {'email': 'user1@example.com', 'first_name': 'User 1'},
179
+ {'email': 'user2@example.com', 'first_name': 'User 2'}
180
+ ]
181
+ })
182
+ ```
183
+
184
+ ### Lists
185
+
186
+ ```python
187
+ # List all lists
188
+ lists = client.lists.list()
189
+
190
+ # Get single list
191
+ lst = client.lists.get(id)
192
+
193
+ # Create list
194
+ lst = client.lists.create({
195
+ 'name': 'Newsletter Subscribers',
196
+ 'description': 'Monthly newsletter'
197
+ })
198
+
199
+ # Update list
200
+ client.lists.update(id, {'name': 'Updated Name'})
201
+
202
+ # Delete list
203
+ client.lists.delete(id)
204
+
205
+ # Get list statistics
206
+ stats = client.lists.stats(id)
207
+ ```
208
+
209
+ ### Segments
210
+
211
+ ```python
212
+ # List segments for a list
213
+ segments = client.segments.list(list_id)
214
+
215
+ # Get single segment
216
+ segment = client.segments.get(id)
217
+
218
+ # Create segment
219
+ segment = client.segments.create(list_id, {
220
+ 'name': 'Active Subscribers',
221
+ 'conditions': [
222
+ {'field': 'status', 'operator': 'equals', 'value': 'active'}
223
+ ]
224
+ })
225
+
226
+ # Update segment
227
+ client.segments.update(id, {'name': 'Updated Name'})
228
+
229
+ # Delete segment
230
+ client.segments.delete(id)
231
+
232
+ # Preview segment (without saving)
233
+ preview = client.segments.preview(list_id, [
234
+ {'field': 'status', 'operator': 'equals', 'value': 'active'}
235
+ ])
236
+
237
+ # Get segment subscribers
238
+ subscribers = client.segments.subscribers(id)
239
+
240
+ # Refresh segment count
241
+ client.segments.refresh(id)
242
+
243
+ # Get segment build logs
244
+ logs = client.segments.logs(id)
245
+
246
+ # Get segment templates
247
+ templates = client.segments.templates()
248
+
249
+ # Get available fields
250
+ fields = client.segments.fields()
251
+ ```
252
+
253
+ ### Templates
254
+
255
+ ```python
256
+ # List all templates
257
+ templates = client.templates.list(limit=20)
258
+
259
+ # Get single template
260
+ template = client.templates.get(id)
261
+
262
+ # Create template
263
+ template = client.templates.create({
264
+ 'name': 'Welcome Email',
265
+ 'subject': 'Welcome!',
266
+ 'html_content': '<h1>Hello {{name}}</h1>',
267
+ 'category': 'transactional'
268
+ })
269
+
270
+ # Update template
271
+ client.templates.update(id, {'name': 'Updated Name'})
272
+
273
+ # Delete template
274
+ client.templates.delete(id)
275
+
276
+ # Duplicate template
277
+ duplicate = client.templates.duplicate(id)
278
+
279
+ # Get templates by category
280
+ templates = client.templates.by_category('newsletter')
281
+
282
+ # Search templates
283
+ results = client.templates.search('welcome')
284
+
285
+ # Get categories
286
+ categories = client.templates.categories()
287
+ ```
288
+
289
+ ### Forms
290
+
291
+ ```python
292
+ # List all forms
293
+ forms = client.forms.list()
294
+
295
+ # Get single form
296
+ form = client.forms.get(id)
297
+
298
+ # Create form
299
+ form = client.forms.create({
300
+ 'name': 'Newsletter Signup',
301
+ 'list_id': 123,
302
+ 'fields': [
303
+ {'name': 'email', 'type': 'email', 'required': True},
304
+ {'name': 'first_name', 'type': 'text', 'required': False}
305
+ ]
306
+ })
307
+
308
+ # Update form
309
+ client.forms.update(id, {'name': 'Updated Name'})
310
+
311
+ # Delete form
312
+ client.forms.delete(id)
313
+
314
+ # Duplicate form
315
+ duplicate = client.forms.duplicate(id)
316
+
317
+ # Get form analytics
318
+ analytics = client.forms.analytics(id)
319
+
320
+ # Get form submissions
321
+ submissions = client.forms.submissions(id)
322
+
323
+ # Get embed code
324
+ embed = client.forms.embed(id)
325
+ ```
326
+
327
+ ### Conversions
328
+
329
+ ```python
330
+ # List all conversion goals
331
+ conversions = client.conversions.list()
332
+
333
+ # Get single conversion goal
334
+ goal = client.conversions.get(id)
335
+
336
+ # Create conversion goal
337
+ goal = client.conversions.create({
338
+ 'name': 'Purchase',
339
+ 'event_type': 'purchase',
340
+ 'value': 100
341
+ })
342
+
343
+ # Update conversion goal
344
+ client.conversions.update(id, {'name': 'Updated Name'})
345
+
346
+ # Delete conversion goal
347
+ client.conversions.delete(id)
348
+
349
+ # Track a conversion
350
+ client.conversions.track({
351
+ 'goal_id': id,
352
+ 'subscriber_id': 123,
353
+ 'value': 50
354
+ })
355
+
356
+ # Get conversions for a goal
357
+ conversions = client.conversions.conversions(id)
358
+
359
+ # Get ROI report
360
+ roi = client.conversions.roi()
361
+
362
+ # Get funnel analysis
363
+ funnel = client.conversions.funnel(id)
364
+ ```
365
+
366
+ ### Landing Pages
367
+
368
+ ```python
369
+ # List all landing pages
370
+ pages = client.landing_pages.list()
371
+
372
+ # Get single landing page
373
+ page = client.landing_pages.get(id)
374
+
375
+ # Create landing page
376
+ page = client.landing_pages.create({
377
+ 'name': 'Thank You Page',
378
+ 'slug': 'thank-you',
379
+ 'html_content': '<h1>Thank you!</h1>'
380
+ })
381
+
382
+ # Update landing page
383
+ client.landing_pages.update(id, {'name': 'Updated Name'})
384
+
385
+ # Delete landing page
386
+ client.landing_pages.delete(id)
387
+
388
+ # Duplicate landing page
389
+ duplicate = client.landing_pages.duplicate(id)
390
+
391
+ # Publish landing page
392
+ client.landing_pages.publish(id)
393
+
394
+ # Unpublish landing page
395
+ client.landing_pages.unpublish(id)
396
+
397
+ # Get landing page analytics
398
+ analytics = client.landing_pages.analytics(id)
399
+
400
+ # Get templates
401
+ templates = client.landing_pages.templates()
402
+ ```
403
+
404
+ ### Workflows
405
+
406
+ ```python
407
+ # List all workflows
408
+ workflows = client.workflows.list()
409
+
410
+ # Get single workflow
411
+ workflow = client.workflows.get(id)
412
+
413
+ # Create workflow
414
+ workflow = client.workflows.create({
415
+ 'name': 'Welcome Series',
416
+ 'nodes': [...],
417
+ 'edges': [...]
418
+ })
419
+
420
+ # Update workflow
421
+ client.workflows.update(id, {'name': 'Updated Name'})
422
+
423
+ # Delete workflow
424
+ client.workflows.delete(id)
425
+
426
+ # Duplicate workflow
427
+ duplicate = client.workflows.duplicate(id)
428
+
429
+ # Activate workflow
430
+ client.workflows.activate(id)
431
+
432
+ # Pause workflow
433
+ client.workflows.pause(id)
434
+
435
+ # Validate workflow
436
+ validation = client.workflows.validate(id)
437
+
438
+ # Get workflow executions
439
+ executions = client.workflows.executions(id)
440
+
441
+ # Get workflow templates
442
+ templates = client.workflows.templates()
443
+
444
+ # Create workflow from template
445
+ workflow = client.workflows.from_template(template_id)
446
+
447
+ # Get available node types
448
+ node_types = client.workflows.node_types()
449
+
450
+ # Get workflow data
451
+ data = client.workflows.get_data(id)
452
+ ```
453
+
454
+ ## Error Handling
455
+
456
+ ```python
457
+ from kirimel import (
458
+ ApiException,
459
+ AuthenticationException,
460
+ RateLimitException,
461
+ ValidationException
462
+ )
463
+
464
+ try:
465
+ campaign = client.campaigns.create(data)
466
+ except AuthenticationException as e:
467
+ # Invalid API key
468
+ print(f"Authentication failed: {e.message}")
469
+ except RateLimitException as e:
470
+ # Too many requests
471
+ print(f"Rate limited. Retry after: {e.retry_after} seconds")
472
+ except ValidationException as e:
473
+ # Invalid data
474
+ print(f"Validation errors: {e.errors}")
475
+ except ApiException as e:
476
+ # General API error
477
+ print(f"API error ({e.status_code}): {e.message}")
478
+ ```
479
+
480
+ ## Logging
481
+
482
+ ```python
483
+ import logging
484
+
485
+ # Set up logging
486
+ logging.basicConfig(level=logging.DEBUG)
487
+
488
+ # The SDK will use the root logger by default
489
+ ```
490
+
491
+ ## Requirements
492
+
493
+ - Python 3.8 or higher
494
+ - requests >= 2.28.0
495
+
496
+ ## License
497
+
498
+ MIT License
499
+
500
+ ## Support
501
+
502
+ - Documentation: https://docs.kirimel.com
503
+ - GitHub: https://github.com/hualiglobal/kirimel-python-sdk
504
+ - Issues: https://github.com/hualiglobal/kirimel-python-sdk/issues