swipeflow-api 1.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,15 @@
1
+ ISC License
2
+
3
+ Copyright (c) 2024 SwipeFlow
4
+
5
+ Permission to use, copy, modify, and/or distribute this software for any
6
+ purpose with or without fee is hereby granted, provided that the above
7
+ copyright notice and this permission notice appear in all copies.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
@@ -0,0 +1,4 @@
1
+ include README.md
2
+ include LICENSE
3
+ include requirements.txt
4
+ recursive-include swipeflow_api py.typed
@@ -0,0 +1,568 @@
1
+ Metadata-Version: 2.4
2
+ Name: swipeflow-api
3
+ Version: 1.1.0
4
+ Summary: Python SDK for SwipeFlow API - Add manual approval steps to your workflows with a Tinder-like swiping interface
5
+ Home-page: https://github.com/swipeflow/swipeflow
6
+ Author: SwipeFlow
7
+ Author-email: SwipeFlow <support@swipeflow.io>
8
+ License: ISC
9
+ Project-URL: Homepage, https://swipeflow.io
10
+ Project-URL: Documentation, https://swipeflow.io/docs
11
+ Project-URL: Repository, https://github.com/swipeflow/swipeflow-api-py
12
+ Project-URL: Issue Tracker, https://github.com/swipeflow/swipeflow-api-py/issues
13
+ Keywords: swipeflow,api,sdk,automation,approval,workflow
14
+ Classifier: Development Status :: 4 - Beta
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: License :: OSI Approved :: ISC License (ISCL)
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.8
19
+ Classifier: Programming Language :: Python :: 3.9
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Operating System :: OS Independent
24
+ Requires-Python: >=3.8
25
+ Description-Content-Type: text/markdown
26
+ License-File: LICENSE
27
+ Requires-Dist: requests>=2.28.0
28
+ Requires-Dist: pydantic>=2.0.0
29
+ Requires-Dist: python-dateutil>=2.8.0
30
+ Requires-Dist: typing-extensions>=4.5.0
31
+ Provides-Extra: dev
32
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
33
+ Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
34
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
35
+ Requires-Dist: black>=23.0.0; extra == "dev"
36
+ Requires-Dist: isort>=5.12.0; extra == "dev"
37
+ Requires-Dist: flake8>=6.0.0; extra == "dev"
38
+ Requires-Dist: mypy>=1.0.0; extra == "dev"
39
+ Requires-Dist: build>=0.10.0; extra == "dev"
40
+ Dynamic: author
41
+ Dynamic: home-page
42
+ Dynamic: license-file
43
+ Dynamic: requires-python
44
+
45
+ # SwipeFlow Python SDK
46
+
47
+ ![Python Version](https://img.shields.io/badge/python-3.8+-blue.svg)
48
+ ![License](https://img.shields.io/badge/license-ISC-green.svg)
49
+ ![Version](https://img.shields.io/badge/version-1.1.0-blue.svg)
50
+
51
+ A pythonic, auto-generated SDK for the SwipeFlow API. Add manual approval steps to your automation workflows with a Tinder-like swiping interface.
52
+
53
+ ## Features
54
+
55
+ - 🚀 **Simple & Pythonic** - Intuitive API that follows Python conventions
56
+ - 🔄 **Auto-Generated** - Built from OpenAPI spec for accuracy and consistency
57
+ - 📦 **Fully Typed** - Complete type hints for IDE autocomplete and type checking
58
+ - ⚡ **Async Ready** - Easy to extend with async/await patterns
59
+ - 🛡️ **Error Handling** - Custom exceptions for different error scenarios
60
+ - 🔑 **Multiple Auth** - Supports API keys and JWT tokens
61
+ - 📋 **Well Documented** - Comprehensive docstrings and examples
62
+
63
+ ## Installation
64
+
65
+ Install from PyPI:
66
+
67
+ ```bash
68
+ pip install swipeflow-api-py
69
+ ```
70
+
71
+ Or install from source:
72
+
73
+ ```bash
74
+ pip install -e .
75
+ ```
76
+
77
+ For development:
78
+
79
+ ```bash
80
+ pip install -e ".[dev]"
81
+ ```
82
+
83
+ ## Quick Start
84
+
85
+ ### Basic Usage
86
+
87
+ ```python
88
+ from swipeflow_api import SwipeFlowClient
89
+
90
+ # Initialize client
91
+ client = SwipeFlowClient(api_key="your-api-key")
92
+
93
+ # List projects
94
+ projects = client.projects.list()
95
+ for project in projects:
96
+ print(f"Project: {project['name']}")
97
+
98
+ # Create a new item
99
+ item = client.items.create(
100
+ project_id="project-123",
101
+ title="Approve new user signup",
102
+ content={
103
+ "type": "TEXT",
104
+ "data": {"message": "New user John Doe signed up"}
105
+ }
106
+ )
107
+ print(f"Item created: {item['id']}")
108
+
109
+ # Approve an item
110
+ client.items.approve(
111
+ project_id="project-123",
112
+ item_id=item['id'],
113
+ comment="User verified"
114
+ )
115
+ ```
116
+
117
+ ### Environment Variable
118
+
119
+ Set the API key as an environment variable instead of passing it directly:
120
+
121
+ ```bash
122
+ export SWIPEFLOW_API_KEY="your-api-key"
123
+ ```
124
+
125
+ Then initialize without the key:
126
+
127
+ ```python
128
+ client = SwipeFlowClient()
129
+ ```
130
+
131
+ ### Context Manager
132
+
133
+ Use the client as a context manager to automatically close connections:
134
+
135
+ ```python
136
+ with SwipeFlowClient(api_key="your-api-key") as client:
137
+ projects = client.projects.list()
138
+ ```
139
+
140
+ ## API Resources
141
+
142
+ ### Projects
143
+
144
+ ```python
145
+ # List projects
146
+ projects = client.projects.list(skip=0, limit=20)
147
+
148
+ # Get a specific project
149
+ project = client.projects.get("project-id")
150
+
151
+ # Create a new project
152
+ project = client.projects.create(
153
+ name="My Project",
154
+ description="Project description"
155
+ )
156
+
157
+ # Update a project
158
+ updated = client.projects.update(
159
+ project_id="project-id",
160
+ name="Updated Name"
161
+ )
162
+
163
+ # Delete a project
164
+ client.projects.delete("project-id")
165
+
166
+ # Add a member to project
167
+ client.projects.add_member(
168
+ project_id="project-id",
169
+ user_id="user-id",
170
+ role="EDITOR" # OWNER, ADMIN, EDITOR, VIEWER
171
+ )
172
+
173
+ # Remove a member
174
+ client.projects.remove_member("project-id", "user-id")
175
+ ```
176
+
177
+ ### Items
178
+
179
+ ```python
180
+ # List items in a project
181
+ items = client.items.list(
182
+ project_id="project-id",
183
+ status="PENDING", # Optional: filter by status
184
+ skip=0,
185
+ limit=20
186
+ )
187
+
188
+ # Get a specific item
189
+ item = client.items.get("project-id", "item-id")
190
+
191
+ # Create an item
192
+ item = client.items.create(
193
+ project_id="project-id",
194
+ title="Review request",
195
+ content={
196
+ "type": "TEXT",
197
+ "data": {"message": "Please review this document"}
198
+ }
199
+ )
200
+
201
+ # Update an item
202
+ updated = client.items.update(
203
+ project_id="project-id",
204
+ item_id="item-id",
205
+ title="Updated title"
206
+ )
207
+
208
+ # Delete an item
209
+ client.items.delete("project-id", "item-id")
210
+
211
+ # Approve an item
212
+ client.items.approve(
213
+ project_id="project-id",
214
+ item_id="item-id",
215
+ comment="Looks good!"
216
+ )
217
+
218
+ # Reject an item
219
+ client.items.reject(
220
+ project_id="project-id",
221
+ item_id="item-id",
222
+ comment="Needs revision"
223
+ )
224
+
225
+ # Request changes
226
+ client.items.request_changes(
227
+ project_id="project-id",
228
+ item_id="item-id",
229
+ comment="Please update section 2"
230
+ )
231
+
232
+ # Get item version history
233
+ versions = client.items.get_versions("project-id", "item-id")
234
+ ```
235
+
236
+ ### Webhooks
237
+
238
+ ```python
239
+ # List webhooks
240
+ webhooks = client.webhooks.list("project-id")
241
+
242
+ # Get a webhook
243
+ webhook = client.webhooks.get("project-id", "webhook-id")
244
+
245
+ # Create a webhook
246
+ webhook = client.webhooks.create(
247
+ project_id="project-id",
248
+ name="My Webhook",
249
+ url="https://example.com/webhook",
250
+ events=["item.created", "item.approved", "item.rejected"]
251
+ )
252
+
253
+ # Update a webhook
254
+ updated = client.webhooks.update(
255
+ project_id="project-id",
256
+ webhook_id="webhook-id",
257
+ name="Updated name",
258
+ active=True
259
+ )
260
+
261
+ # Delete a webhook
262
+ client.webhooks.delete("project-id", "webhook-id")
263
+
264
+ # Test a webhook
265
+ result = client.webhooks.test("project-id", "webhook-id")
266
+ ```
267
+
268
+ ### API Keys
269
+
270
+ ```python
271
+ # List API keys
272
+ keys = client.api_keys.list()
273
+
274
+ # Create a new API key
275
+ key = client.api_keys.create(name="Production Key")
276
+ print(f"Key: {key['key']}") # Save this securely!
277
+
278
+ # Delete an API key
279
+ client.api_keys.delete("key-id")
280
+ ```
281
+
282
+ ### Authentication
283
+
284
+ ```python
285
+ # Get current user profile
286
+ profile = client.auth.get_profile()
287
+
288
+ # Update profile
289
+ updated = client.auth.update_profile(
290
+ name="John Doe",
291
+ avatar_url="https://example.com/avatar.jpg"
292
+ )
293
+ ```
294
+
295
+ ## Error Handling
296
+
297
+ The SDK provides specific exception classes for different error scenarios:
298
+
299
+ ```python
300
+ from swipeflow_api import (
301
+ SwipeFlowError,
302
+ AuthenticationError,
303
+ AuthorizationError,
304
+ NotFoundError,
305
+ ValidationError,
306
+ ServerError,
307
+ )
308
+
309
+ try:
310
+ client.items.get("project-id", "item-id")
311
+ except NotFoundError as e:
312
+ print(f"Item not found: {e.message}")
313
+ except AuthenticationError as e:
314
+ print(f"Authentication failed: {e.message}")
315
+ except SwipeFlowError as e:
316
+ print(f"API error: {e.message}")
317
+ ```
318
+
319
+ ## Models
320
+
321
+ The SDK includes Pydantic models for type safety:
322
+
323
+ ```python
324
+ from swipeflow_api.models import (
325
+ Item,
326
+ Project,
327
+ User,
328
+ Webhook,
329
+ ItemStatus,
330
+ DecisionType,
331
+ ProjectRole,
332
+ ContentType,
333
+ WebhookEvent,
334
+ )
335
+
336
+ # Models are used for type hints
337
+ def process_item(item: Item) -> None:
338
+ print(f"Processing {item.title} (status: {item.status})")
339
+ ```
340
+
341
+ ## Advanced Configuration
342
+
343
+ ### Custom Base URL
344
+
345
+ ```python
346
+ client = SwipeFlowClient(
347
+ api_key="your-api-key",
348
+ base_url="https://staging-api.swipeflow.io"
349
+ )
350
+ ```
351
+
352
+ ### Timeout and SSL
353
+
354
+ ```python
355
+ client = SwipeFlowClient(
356
+ api_key="your-api-key",
357
+ timeout=60,
358
+ verify_ssl=True # Set to False only in development!
359
+ )
360
+ ```
361
+
362
+ ### Direct Request Method
363
+
364
+ For advanced use cases, access the underlying request method:
365
+
366
+ ```python
367
+ response = client.request(
368
+ method="POST",
369
+ endpoint="/v1/projects/123/items",
370
+ json_data={"title": "Custom item"},
371
+ params={"custom": "param"}
372
+ )
373
+ ```
374
+
375
+ ## Development
376
+
377
+ ### Setup Development Environment
378
+
379
+ ```bash
380
+ git clone https://github.com/swipeflow/swipeflow.git
381
+ cd sdk/swipeflow-py-api
382
+ pip install -e ".[dev]"
383
+ ```
384
+
385
+ ### Code Quality
386
+
387
+ ```bash
388
+ # Format code
389
+ black swipeflow_api/
390
+
391
+ # Sort imports
392
+ isort swipeflow_api/
393
+
394
+ # Lint
395
+ flake8 swipeflow_api/
396
+
397
+ # Type checking
398
+ mypy swipeflow_api/
399
+
400
+ # Run tests
401
+ pytest tests/
402
+
403
+ # Generate coverage report
404
+ pytest --cov=swipeflow_api tests/
405
+ ```
406
+
407
+ ### Regenerate from OpenAPI
408
+
409
+ The SDK can be regenerated from the backend's OpenAPI spec:
410
+
411
+ ```bash
412
+ # Using Python
413
+ python scripts/generate.py
414
+
415
+ # Using bash
416
+ bash scripts/generate.sh
417
+ ```
418
+
419
+ ## Publishing
420
+
421
+ ### Build Package
422
+
423
+ ```bash
424
+ python -m build
425
+ ```
426
+
427
+ ### Publish to PyPI
428
+
429
+ ```bash
430
+ python -m twine upload dist/*
431
+ ```
432
+
433
+ ## Architecture
434
+
435
+ ### Project Structure
436
+
437
+ ```
438
+ swipeflow-py-api/
439
+ ├── swipeflow_api/ # Main package
440
+ │ ├── __init__.py # Public API
441
+ │ ├── client.py # Main client
442
+ │ ├── resources.py # Resource classes
443
+ │ ├── models.py # Pydantic models
444
+ │ ├── exceptions.py # Exception classes
445
+ │ └── generated/ # Auto-generated code (from OpenAPI)
446
+ ├── scripts/
447
+ │ ├── generate.py # Generation script
448
+ │ └── generate.sh # Bash generation script
449
+ ├── tests/ # Test suite
450
+ ├── setup.py # Package setup
451
+ ├── pyproject.toml # Modern Python packaging
452
+ └── README.md # This file
453
+ ```
454
+
455
+ ### Auto-Generation
456
+
457
+ The client is auto-generated from the OpenAPI spec (`backend/openapi.json`) using OpenAPI Generator. This ensures:
458
+
459
+ - ✅ Consistency with backend API
460
+ - ✅ Type-safe models
461
+ - ✅ Complete API coverage
462
+ - ✅ Automatic updates as API evolves
463
+
464
+ The SDK provides a pythonic wrapper (`client.py`, `resources.py`) on top of generated code for better developer experience.
465
+
466
+ ## Examples
467
+
468
+ ### Batch Process Items
469
+
470
+ ```python
471
+ client = SwipeFlowClient(api_key="key")
472
+
473
+ # Get all pending items
474
+ items = client.items.list(
475
+ project_id="project-123",
476
+ status="PENDING",
477
+ limit=100
478
+ )
479
+
480
+ # Process them
481
+ for item in items:
482
+ if "urgent" in item.get("title", "").lower():
483
+ client.items.approve(
484
+ project_id="project-123",
485
+ item_id=item["id"],
486
+ comment="Urgent - approved"
487
+ )
488
+ ```
489
+
490
+ ### Setup Webhooks
491
+
492
+ ```python
493
+ # Create webhook for all approval events
494
+ client.webhooks.create(
495
+ project_id="project-123",
496
+ name="Approval Events",
497
+ url="https://myapp.com/webhooks/approvals",
498
+ events=[
499
+ "item.approved",
500
+ "item.rejected",
501
+ "item.change_requested"
502
+ ]
503
+ )
504
+ ```
505
+
506
+ ### Monitor Project
507
+
508
+ ```python
509
+ project = client.projects.get("project-123")
510
+ print(f"Project: {project['name']}")
511
+ print(f"Members: {len(project.get('members', []))}")
512
+ print(f"Items: {project.get('item_count', 0)}")
513
+ print(f"Webhooks: {project.get('webhook_count', 0)}")
514
+ ```
515
+
516
+ ## Troubleshooting
517
+
518
+ ### "API key not provided"
519
+
520
+ Make sure you're passing the API key or setting the `SWIPEFLOW_API_KEY` environment variable:
521
+
522
+ ```python
523
+ # Option 1: Pass directly
524
+ client = SwipeFlowClient(api_key="sk_test_...")
525
+
526
+ # Option 2: Environment variable
527
+ export SWIPEFLOW_API_KEY="sk_test_..."
528
+ client = SwipeFlowClient()
529
+ ```
530
+
531
+ ### Network Errors
532
+
533
+ The client includes automatic retry logic for transient failures. For persistent issues:
534
+
535
+ ```python
536
+ # Increase timeout
537
+ client = SwipeFlowClient(api_key="key", timeout=60)
538
+
539
+ # Check API status
540
+ # Visit https://status.swipeflow.io/
541
+ ```
542
+
543
+ ### Type Checking Issues
544
+
545
+ Ensure you're using Python 3.8+ and install type stubs:
546
+
547
+ ```bash
548
+ pip install types-requests
549
+ ```
550
+
551
+ ## Support
552
+
553
+ - 📖 [Documentation](https://docs.swipeflow.io)
554
+ - 🐛 [Report Issues](https://github.com/swipeflow/swipeflow/issues)
555
+ - 💬 [Discussions](https://github.com/swipeflow/swipeflow/discussions)
556
+ - 📧 [Email](mailto:support@swipeflow.io)
557
+
558
+ ## License
559
+
560
+ ISC License - See LICENSE file for details
561
+
562
+ ## Contributing
563
+
564
+ Contributions are welcome! Please read our [contributing guidelines](../../CONTRIBUTING.md) first.
565
+
566
+ ---
567
+
568
+ **Made with ❤️ by [SwipeFlow](https://swipeflow.io)**