oppulence-billflowap 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.
@@ -0,0 +1,467 @@
1
+ Metadata-Version: 2.4
2
+ Name: oppulence-billflowap
3
+ Version: 0.1.1
4
+ Summary: BillFlow AP SDK - Execute AP workflows programmatically
5
+ Home-page: https://github.com/simstudioai/sim
6
+ Author: Sim
7
+ Author-email: Oppulence Engineering <support@oppulence.io>
8
+ License: Apache-2.0
9
+ Project-URL: Homepage, https://github.com/Oppulence-Engineering/billflowAP
10
+ Project-URL: Documentation, https://github.com/Oppulence-Engineering/billflowAP
11
+ Project-URL: Repository, https://github.com/Oppulence-Engineering/billflowAP
12
+ Project-URL: Bug Reports, https://github.com/Oppulence-Engineering/billflowAP/issues
13
+ Keywords: billflowap,billflow,ap,accounts-payable,invoice,sdk,api,automation
14
+ Classifier: Development Status :: 4 - Beta
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: License :: OSI Approved :: Apache Software License
17
+ Classifier: Operating System :: OS Independent
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.8
20
+ Classifier: Programming Language :: Python :: 3.9
21
+ Classifier: Programming Language :: Python :: 3.10
22
+ Classifier: Programming Language :: Python :: 3.11
23
+ Classifier: Programming Language :: Python :: 3.12
24
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
25
+ Classifier: Topic :: Office/Business :: Financial :: Accounting
26
+ Classifier: Topic :: Office/Business :: Financial
27
+ Requires-Python: >=3.8
28
+ Description-Content-Type: text/markdown
29
+ Requires-Dist: requests>=2.25.0
30
+ Requires-Dist: typing-extensions>=4.0.0; python_version < "3.10"
31
+ Provides-Extra: dev
32
+ Requires-Dist: pytest>=6.0.0; extra == "dev"
33
+ Requires-Dist: pytest-asyncio>=0.18.0; extra == "dev"
34
+ Requires-Dist: black>=22.0.0; extra == "dev"
35
+ Requires-Dist: flake8>=4.0.0; extra == "dev"
36
+ Requires-Dist: mypy>=0.910; extra == "dev"
37
+ Requires-Dist: isort>=5.0.0; extra == "dev"
38
+ Requires-Dist: types-requests>=2.25.0; extra == "dev"
39
+ Dynamic: author
40
+ Dynamic: home-page
41
+ Dynamic: requires-python
42
+
43
+ # Sim Python SDK
44
+
45
+ The official Python SDK for [Sim](https://sim.ai), allowing you to execute workflows programmatically from your Python applications.
46
+
47
+ ## Installation
48
+
49
+ ```bash
50
+ pip install simstudio-sdk
51
+ ```
52
+
53
+ ## Quick Start
54
+
55
+ ```python
56
+ import os
57
+ from simstudio import SimStudioClient
58
+
59
+ # Initialize the client
60
+ client = SimStudioClient(
61
+ api_key=os.getenv("SIM_API_KEY", "your-api-key-here"),
62
+ base_url="https://sim.ai" # optional, defaults to https://sim.ai
63
+ )
64
+
65
+ # Execute a workflow
66
+ try:
67
+ result = client.execute_workflow("workflow-id")
68
+ print("Workflow executed successfully:", result)
69
+ except Exception as error:
70
+ print("Workflow execution failed:", error)
71
+ ```
72
+
73
+ ## API Reference
74
+
75
+ ### SimStudioClient
76
+
77
+ #### Constructor
78
+
79
+ ```python
80
+ SimStudioClient(api_key: str, base_url: str = "https://sim.ai")
81
+ ```
82
+
83
+ - `api_key` (str): Your Sim API key
84
+ - `base_url` (str, optional): Base URL for the Sim API (defaults to `https://sim.ai`)
85
+
86
+ #### Methods
87
+
88
+ ##### execute_workflow(workflow_id, input_data=None, timeout=30.0)
89
+
90
+ Execute a workflow with optional input data.
91
+
92
+ ```python
93
+ result = client.execute_workflow(
94
+ "workflow-id",
95
+ input_data={"message": "Hello, world!"},
96
+ timeout=30.0 # 30 seconds
97
+ )
98
+ ```
99
+
100
+ **Parameters:**
101
+ - `workflow_id` (str): The ID of the workflow to execute
102
+ - `input_data` (dict, optional): Input data to pass to the workflow. File objects are automatically converted to base64.
103
+ - `timeout` (float): Timeout in seconds (default: 30.0)
104
+
105
+ **Returns:** `WorkflowExecutionResult`
106
+
107
+ ##### get_workflow_status(workflow_id)
108
+
109
+ Get the status of a workflow (deployment status, etc.).
110
+
111
+ ```python
112
+ status = client.get_workflow_status("workflow-id")
113
+ print("Is deployed:", status.is_deployed)
114
+ ```
115
+
116
+ **Parameters:**
117
+ - `workflow_id` (str): The ID of the workflow
118
+
119
+ **Returns:** `WorkflowStatus`
120
+
121
+ ##### validate_workflow(workflow_id)
122
+
123
+ Validate that a workflow is ready for execution.
124
+
125
+ ```python
126
+ is_ready = client.validate_workflow("workflow-id")
127
+ if is_ready:
128
+ # Workflow is deployed and ready
129
+ pass
130
+ ```
131
+
132
+ **Parameters:**
133
+ - `workflow_id` (str): The ID of the workflow
134
+
135
+ **Returns:** `bool`
136
+
137
+ ##### execute_workflow_sync(workflow_id, input_data=None, timeout=30.0)
138
+
139
+ Execute a workflow and poll for completion (useful for long-running workflows).
140
+
141
+ ```python
142
+ result = client.execute_workflow_sync(
143
+ "workflow-id",
144
+ input_data={"data": "some input"},
145
+ timeout=60.0
146
+ )
147
+ ```
148
+
149
+ **Parameters:**
150
+ - `workflow_id` (str): The ID of the workflow to execute
151
+ - `input_data` (dict, optional): Input data to pass to the workflow
152
+ - `timeout` (float): Timeout for the initial request in seconds
153
+
154
+ **Returns:** `WorkflowExecutionResult`
155
+
156
+ ##### set_api_key(api_key)
157
+
158
+ Update the API key.
159
+
160
+ ```python
161
+ client.set_api_key("new-api-key")
162
+ ```
163
+
164
+ ##### set_base_url(base_url)
165
+
166
+ Update the base URL.
167
+
168
+ ```python
169
+ client.set_base_url("https://my-custom-domain.com")
170
+ ```
171
+
172
+ ##### close()
173
+
174
+ Close the underlying HTTP session.
175
+
176
+ ```python
177
+ client.close()
178
+ ```
179
+
180
+ ## Data Classes
181
+
182
+ ### WorkflowExecutionResult
183
+
184
+ ```python
185
+ @dataclass
186
+ class WorkflowExecutionResult:
187
+ success: bool
188
+ output: Optional[Any] = None
189
+ error: Optional[str] = None
190
+ logs: Optional[list] = None
191
+ metadata: Optional[Dict[str, Any]] = None
192
+ trace_spans: Optional[list] = None
193
+ total_duration: Optional[float] = None
194
+ ```
195
+
196
+ ### WorkflowStatus
197
+
198
+ ```python
199
+ @dataclass
200
+ class WorkflowStatus:
201
+ is_deployed: bool
202
+ deployed_at: Optional[str] = None
203
+ needs_redeployment: bool = False
204
+ ```
205
+
206
+ ### SimStudioError
207
+
208
+ ```python
209
+ class SimStudioError(Exception):
210
+ def __init__(self, message: str, code: Optional[str] = None, status: Optional[int] = None):
211
+ super().__init__(message)
212
+ self.code = code
213
+ self.status = status
214
+ ```
215
+
216
+ ## Examples
217
+
218
+ ### Basic Workflow Execution
219
+
220
+ ```python
221
+ import os
222
+ from simstudio import SimStudioClient
223
+
224
+ client = SimStudioClient(api_key=os.getenv("SIM_API_KEY"))
225
+
226
+ def run_workflow():
227
+ try:
228
+ # Check if workflow is ready
229
+ is_ready = client.validate_workflow("my-workflow-id")
230
+ if not is_ready:
231
+ raise Exception("Workflow is not deployed or ready")
232
+
233
+ # Execute the workflow
234
+ result = client.execute_workflow(
235
+ "my-workflow-id",
236
+ input_data={
237
+ "message": "Process this data",
238
+ "user_id": "12345"
239
+ }
240
+ )
241
+
242
+ if result.success:
243
+ print("Output:", result.output)
244
+ print("Duration:", result.metadata.get("duration") if result.metadata else None)
245
+ else:
246
+ print("Workflow failed:", result.error)
247
+
248
+ except Exception as error:
249
+ print("Error:", error)
250
+
251
+ run_workflow()
252
+ ```
253
+
254
+ ### Error Handling
255
+
256
+ ```python
257
+ from simstudio import SimStudioClient, SimStudioError
258
+ import os
259
+
260
+ client = SimStudioClient(api_key=os.getenv("SIM_API_KEY"))
261
+
262
+ def execute_with_error_handling():
263
+ try:
264
+ result = client.execute_workflow("workflow-id")
265
+ return result
266
+ except SimStudioError as error:
267
+ if error.code == "UNAUTHORIZED":
268
+ print("Invalid API key")
269
+ elif error.code == "TIMEOUT":
270
+ print("Workflow execution timed out")
271
+ elif error.code == "USAGE_LIMIT_EXCEEDED":
272
+ print("Usage limit exceeded")
273
+ elif error.code == "INVALID_JSON":
274
+ print("Invalid JSON in request body")
275
+ else:
276
+ print(f"Workflow error: {error}")
277
+ raise
278
+ except Exception as error:
279
+ print(f"Unexpected error: {error}")
280
+ raise
281
+ ```
282
+
283
+ ### Context Manager Usage
284
+
285
+ ```python
286
+ from simstudio import SimStudioClient
287
+ import os
288
+
289
+ # Using context manager to automatically close the session
290
+ with SimStudioClient(api_key=os.getenv("SIM_API_KEY")) as client:
291
+ result = client.execute_workflow("workflow-id")
292
+ print("Result:", result)
293
+ # Session is automatically closed here
294
+ ```
295
+
296
+ ### Environment Configuration
297
+
298
+ ```python
299
+ import os
300
+ from simstudio import SimStudioClient
301
+
302
+ # Using environment variables
303
+ client = SimStudioClient(
304
+ api_key=os.getenv("SIM_API_KEY"),
305
+ base_url=os.getenv("SIM_BASE_URL", "https://sim.ai")
306
+ )
307
+ ```
308
+
309
+ ### File Upload
310
+
311
+ File objects are automatically detected and converted to base64 format. Include them in your input under the field name matching your workflow's API trigger input format:
312
+
313
+ The SDK converts file objects to this format:
314
+ ```python
315
+ {
316
+ 'type': 'file',
317
+ 'data': 'data:mime/type;base64,base64data',
318
+ 'name': 'filename',
319
+ 'mime': 'mime/type'
320
+ }
321
+ ```
322
+
323
+ Alternatively, you can manually provide files using the URL format:
324
+ ```python
325
+ {
326
+ 'type': 'url',
327
+ 'data': 'https://example.com/file.pdf',
328
+ 'name': 'file.pdf',
329
+ 'mime': 'application/pdf'
330
+ }
331
+ ```
332
+
333
+ ```python
334
+ from simstudio import SimStudioClient
335
+ import os
336
+
337
+ client = SimStudioClient(api_key=os.getenv("SIM_API_KEY"))
338
+
339
+ # Upload a single file - include it under the field name from your API trigger
340
+ with open('document.pdf', 'rb') as f:
341
+ result = client.execute_workflow(
342
+ 'workflow-id',
343
+ input_data={
344
+ 'documents': [f], # Must match your workflow's "files" field name
345
+ 'instructions': 'Analyze this document'
346
+ }
347
+ )
348
+
349
+ # Upload multiple files
350
+ with open('doc1.pdf', 'rb') as f1, open('doc2.pdf', 'rb') as f2:
351
+ result = client.execute_workflow(
352
+ 'workflow-id',
353
+ input_data={
354
+ 'attachments': [f1, f2], # Must match your workflow's "files" field name
355
+ 'query': 'Compare these documents'
356
+ }
357
+ )
358
+ ```
359
+
360
+ ### Batch Workflow Execution
361
+
362
+ ```python
363
+ from simstudio import SimStudioClient
364
+ import os
365
+
366
+ client = SimStudioClient(api_key=os.getenv("SIM_API_KEY"))
367
+
368
+ def execute_workflows_batch(workflow_data_pairs):
369
+ """Execute multiple workflows with different input data."""
370
+ results = []
371
+
372
+ for workflow_id, input_data in workflow_data_pairs:
373
+ try:
374
+ # Validate workflow before execution
375
+ if not client.validate_workflow(workflow_id):
376
+ print(f"Skipping {workflow_id}: not deployed")
377
+ continue
378
+
379
+ result = client.execute_workflow(workflow_id, input_data)
380
+ results.append({
381
+ "workflow_id": workflow_id,
382
+ "success": result.success,
383
+ "output": result.output,
384
+ "error": result.error
385
+ })
386
+
387
+ except Exception as error:
388
+ results.append({
389
+ "workflow_id": workflow_id,
390
+ "success": False,
391
+ "error": str(error)
392
+ })
393
+
394
+ return results
395
+
396
+ # Example usage
397
+ workflows = [
398
+ ("workflow-1", {"type": "analysis", "data": "sample1"}),
399
+ ("workflow-2", {"type": "processing", "data": "sample2"}),
400
+ ]
401
+
402
+ results = execute_workflows_batch(workflows)
403
+ for result in results:
404
+ print(f"Workflow {result['workflow_id']}: {'Success' if result['success'] else 'Failed'}")
405
+ ```
406
+
407
+ ## Getting Your API Key
408
+
409
+ 1. Log in to your [Sim](https://sim.ai) account
410
+ 2. Navigate to your workflow
411
+ 3. Click on "Deploy" to deploy your workflow
412
+ 4. Select or create an API key during the deployment process
413
+ 5. Copy the API key to use in your application
414
+
415
+ ## Development
416
+
417
+ ### Running Tests
418
+
419
+ To run the tests locally:
420
+
421
+ 1. Clone the repository and navigate to the Python SDK directory:
422
+ ```bash
423
+ cd packages/python-sdk
424
+ ```
425
+
426
+ 2. Create and activate a virtual environment:
427
+ ```bash
428
+ python3 -m venv venv
429
+ source venv/bin/activate # On Windows: venv\Scripts\activate
430
+ ```
431
+
432
+ 3. Install the package in development mode with test dependencies:
433
+ ```bash
434
+ pip install -e ".[dev]"
435
+ ```
436
+
437
+ 4. Run the tests:
438
+ ```bash
439
+ pytest tests/ -v
440
+ ```
441
+
442
+ ### Code Quality
443
+
444
+ Run code quality checks:
445
+
446
+ ```bash
447
+ # Code formatting
448
+ black simstudio/
449
+
450
+ # Linting
451
+ flake8 simstudio/ --max-line-length=100
452
+
453
+ # Type checking
454
+ mypy simstudio/
455
+
456
+ # Import sorting
457
+ isort simstudio/
458
+ ```
459
+
460
+ ## Requirements
461
+
462
+ - Python 3.8+
463
+ - requests >= 2.25.0
464
+
465
+ ## License
466
+
467
+ Apache-2.0