loom-core 0.1.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.
Files changed (50) hide show
  1. loom_core-0.1.0.dist-info/METADATA +342 -0
  2. loom_core-0.1.0.dist-info/RECORD +50 -0
  3. loom_core-0.1.0.dist-info/WHEEL +5 -0
  4. loom_core-0.1.0.dist-info/entry_points.txt +2 -0
  5. loom_core-0.1.0.dist-info/licenses/LICENSE +21 -0
  6. loom_core-0.1.0.dist-info/top_level.txt +1 -0
  7. src/__init__.py +45 -0
  8. src/cli/__init__.py +5 -0
  9. src/cli/cli.py +246 -0
  10. src/common/activity.py +30 -0
  11. src/common/config.py +9 -0
  12. src/common/errors.py +64 -0
  13. src/common/workflow.py +56 -0
  14. src/core/__init__.py +0 -0
  15. src/core/compiled.py +41 -0
  16. src/core/context.py +256 -0
  17. src/core/engine.py +106 -0
  18. src/core/handle.py +166 -0
  19. src/core/logger.py +60 -0
  20. src/core/runner.py +53 -0
  21. src/core/state.py +96 -0
  22. src/core/worker.py +147 -0
  23. src/core/workflow.py +168 -0
  24. src/database/__init__.py +0 -0
  25. src/database/db.py +716 -0
  26. src/decorators/__init__.py +0 -0
  27. src/decorators/activity.py +126 -0
  28. src/decorators/workflow.py +46 -0
  29. src/lib/progress.py +109 -0
  30. src/lib/utils.py +25 -0
  31. src/migrations/down/001_setup_pragma.sql +5 -0
  32. src/migrations/down/002_create_workflows.sql +3 -0
  33. src/migrations/down/003.create_events.sql +3 -0
  34. src/migrations/down/004.create_tasks.sql +3 -0
  35. src/migrations/down/005.create_indexes.sql +5 -0
  36. src/migrations/down/006_auto_update_triggers.sql +4 -0
  37. src/migrations/down/007_create_logs.sql +1 -0
  38. src/migrations/up/001_setup_pragma.sql +11 -0
  39. src/migrations/up/002_create_workflows.sql +15 -0
  40. src/migrations/up/003_create_events.sql +13 -0
  41. src/migrations/up/004_create_tasks.sql +23 -0
  42. src/migrations/up/005_create_indexes.sql +11 -0
  43. src/migrations/up/006_auto_update_triggers.sql +19 -0
  44. src/migrations/up/007_create_logs.sql +10 -0
  45. src/schemas/__init__.py +0 -0
  46. src/schemas/activity.py +13 -0
  47. src/schemas/database.py +17 -0
  48. src/schemas/events.py +70 -0
  49. src/schemas/tasks.py +58 -0
  50. src/schemas/workflow.py +33 -0
@@ -0,0 +1,342 @@
1
+ Metadata-Version: 2.4
2
+ Name: loom-core
3
+ Version: 0.1.0
4
+ Summary: Durable workflow orchestration engine for Python
5
+ Home-page: https://github.com/satadeep3927/loom
6
+ Author: Satadeep Dasgupta
7
+ Author-email: Satadeep Dasgupta <satadeep.dasgupta@brainiuminfotech.com>
8
+ License: MIT
9
+ Project-URL: Homepage, https://github.com/satadeep3927/loom
10
+ Project-URL: Documentation, https://github.com/satadeep3927/loom/blob/main/README.md
11
+ Project-URL: Repository, https://github.com/satadeep3927/loom
12
+ Project-URL: Issues, https://github.com/satadeep3927/loom/issues
13
+ Keywords: workflow,orchestration,durable,event-sourcing,temporal
14
+ Classifier: Development Status :: 3 - Alpha
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
17
+ Classifier: License :: OSI Approved :: MIT License
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Framework :: AsyncIO
21
+ Requires-Python: >=3.12
22
+ Description-Content-Type: text/markdown
23
+ License-File: LICENSE
24
+ Requires-Dist: aiosqlite>=0.19.0
25
+ Requires-Dist: click>=8.0.0
26
+ Requires-Dist: rich>=13.0.0
27
+ Provides-Extra: dev
28
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
29
+ Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
30
+ Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
31
+ Requires-Dist: mypy>=1.0.0; extra == "dev"
32
+ Requires-Dist: black>=23.0.0; extra == "dev"
33
+ Requires-Dist: isort>=5.12.0; extra == "dev"
34
+ Requires-Dist: ruff>=0.1.0; extra == "dev"
35
+ Dynamic: author
36
+ Dynamic: home-page
37
+ Dynamic: license-file
38
+ Dynamic: requires-python
39
+
40
+ # Loom - Durable Workflow Orchestration
41
+
42
+ [![Python 3.12+](https://img.shields.io/badge/python-3.12+-blue.svg)](https://www.python.org/downloads/)
43
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
44
+ [![PyPI](https://img.shields.io/badge/pypi-loom--core-blue)](https://pypi.org/project/loom-core/)
45
+
46
+ A Python-based durable workflow orchestration engine inspired by [Temporal](https://temporal.io/) and [Durable Task Framework](https://github.com/Azure/durabletask). Loom provides event-sourced, deterministic workflow execution with automatic recovery and replay capabilities.
47
+
48
+ ## Features
49
+
50
+ - **Event Sourcing**: All workflow state changes persisted as immutable events
51
+ - **Deterministic Replay**: Workflows reconstruct from event history for recovery
52
+ - **Type Safe**: Full generic typing support with `Workflow[InputT, StateT]`
53
+ - **Async First**: Built on asyncio for high-performance concurrent execution
54
+ - **Durable Execution**: Workflows survive process crashes and auto-recover
55
+ - **Beautiful CLI**: Rich console interface with progress tracking
56
+ - **Well Tested**: Comprehensive test suite with pytest
57
+
58
+ ## Quick Start
59
+
60
+ ### Installation
61
+
62
+ ```bash
63
+ pip install loom-core
64
+ ```
65
+
66
+ Or install from source:
67
+
68
+ ```bash
69
+ git clone https://github.com/yourusername/loom.git
70
+ cd loom
71
+ pip install -e .
72
+ ```
73
+
74
+ ### Define a Workflow
75
+
76
+ ```python
77
+ import asyncio
78
+ from typing import TypedDict
79
+ import loom
80
+
81
+
82
+ # Define your data types
83
+ class OrderInput(TypedDict):
84
+ order_id: str
85
+ customer_email: str
86
+
87
+
88
+ class OrderState(TypedDict):
89
+ payment_confirmed: bool
90
+ email_sent: bool
91
+
92
+
93
+ # Define activities (side effects)
94
+ @loom.activity(name="process_payment", retry_count=3, timeout_seconds=30)
95
+ async def process_payment(order_id: str) -> bool:
96
+ # Call payment API
97
+ return True
98
+
99
+
100
+ @loom.activity(name="send_email", retry_count=2)
101
+ async def send_confirmation_email(email: str, order_id: str) -> None:
102
+ # Send email via service
103
+ pass
104
+
105
+
106
+ # Define workflow
107
+ @loom.workflow(name="OrderProcessing", version="1.0.0")
108
+ class OrderWorkflow(loom.Workflow[OrderInput, OrderState]):
109
+
110
+ @loom.step(name="process_payment")
111
+ async def payment_step(self, ctx: loom.WorkflowContext[OrderInput, OrderState]):
112
+ success = await ctx.activity(process_payment, ctx.input["order_id"])
113
+ await ctx.state.set("payment_confirmed", success)
114
+ ctx.logger.info(f"Payment processed: {success}")
115
+
116
+ @loom.step(name="send_confirmation")
117
+ async def notification_step(self, ctx: loom.WorkflowContext[OrderInput, OrderState]):
118
+ if ctx.state["payment_confirmed"]:
119
+ await ctx.activity(
120
+ send_confirmation_email,
121
+ ctx.input["customer_email"],
122
+ ctx.input["order_id"]
123
+ )
124
+ await ctx.state.set("email_sent", True)
125
+ ctx.logger.info("Confirmation email sent")
126
+ ```
127
+
128
+ **Note**: For state updates, use:
129
+ - `await ctx.state.set("key", value)` for single values
130
+ - `await ctx.state.update(key=lambda _: asyncio.sleep(0, value))` for batch updates (requires awaitable)
131
+
132
+ See [STATE_MANAGEMENT.md](STATE_MANAGEMENT.md) for detailed examples.
133
+
134
+ ### Start a Workflow
135
+
136
+ ```python
137
+ async def main():
138
+ db = loom.Database()
139
+ async with db:
140
+ # Initialize database
141
+ await db.migrate_up()
142
+
143
+ # Start workflow
144
+ handle = await db.start_workflow(
145
+ OrderWorkflow,
146
+ workflow_input=OrderInput(
147
+ order_id="ORD-12345",
148
+ customer_email="customer@example.com"
149
+ ),
150
+ initial_state=OrderState(
151
+ payment_confirmed=False,
152
+ email_sent=False
153
+ ),
154
+ )
155
+
156
+ print(f"Workflow started: {handle.workflow_id}")
157
+
158
+ # Execute workflow tasks
159
+ while True:
160
+ task_executed = await loom.run_once()
161
+ if not task_executed:
162
+ break
163
+
164
+
165
+ if __name__ == "__main__":
166
+ asyncio.run(main())
167
+ ```
168
+
169
+ ### Run the Worker
170
+
171
+ ```bash
172
+ # Initialize database
173
+ loom init
174
+
175
+ # Start worker with 4 concurrent task processors
176
+ loom worker
177
+
178
+ # Custom configuration
179
+ loom worker --workers 8 --poll-interval 1.0
180
+ ```
181
+
182
+ ## CLI Commands
183
+
184
+ ```bash
185
+ # Initialize database
186
+ loom init
187
+
188
+ # Start distributed worker
189
+ loom worker [--workers 4] [--poll-interval 0.5]
190
+
191
+ # List workflows
192
+ loom list [--limit 50] [--status RUNNING]
193
+
194
+ # Inspect workflow details
195
+ loom inspect <workflow-id> [--events]
196
+
197
+ # Show database statistics
198
+ loom stats
199
+ ```
200
+
201
+ ## 🏗️ Architecture
202
+
203
+ ### Core Components
204
+
205
+ ```
206
+ ┌─────────────────────────────────────────────────────────┐
207
+ │ Workflow │
208
+ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
209
+ │ │ Step 1 │→ │ Step 2 │→ │ Step 3 │ │
210
+ │ └──────────┘ └──────────┘ └──────────┘ │
211
+ └─────────────────────────────────────────────────────────┘
212
+
213
+ ┌─────────────────────────────────────────────────────────┐
214
+ │ WorkflowContext │
215
+ │ • State Management (StateProxy) │
216
+ │ • Activity Execution │
217
+ │ • Event Replay & Cursor │
218
+ │ • Logger (replay-safe) │
219
+ └─────────────────────────────────────────────────────────┘
220
+
221
+ ┌─────────────────────────────────────────────────────────┐
222
+ │ Engine │
223
+ │ • replay_until_block() - Step execution │
224
+ │ • replay_activity() - Activity retry │
225
+ │ • Event matching & determinism │
226
+ └─────────────────────────────────────────────────────────┘
227
+
228
+ ┌─────────────────────────────────────────────────────────┐
229
+ │ Database (SQLite) │
230
+ │ • workflows • events • tasks • logs │
231
+ └─────────────────────────────────────────────────────────┘
232
+ ```
233
+
234
+ ### Event Types
235
+
236
+ - `WORKFLOW_STARTED` - Workflow initialization
237
+ - `WORKFLOW_COMPLETED` - Successful completion
238
+ - `WORKFLOW_FAILED` - Fatal error occurred
239
+ - `STATE_SET` - Single state key updated
240
+ - `STATE_UPDATE` - Batch state update
241
+ - `ACTIVITY_SCHEDULED` - Activity queued for execution
242
+ - `ACTIVITY_COMPLETED` - Activity finished successfully
243
+ - `ACTIVITY_FAILED` - Activity permanently failed
244
+ - `TIMER_FIRED` - Sleep/delay completed
245
+ - `SIGNAL_RECEIVED` - External signal received
246
+
247
+ ## 📚 Documentation
248
+
249
+ See [`.copilot-instructions.md`](.copilot-instructions.md) for comprehensive development guidelines including:
250
+
251
+ - Event sourcing patterns
252
+ - Deterministic execution rules
253
+ - Activity best practices
254
+ - Testing strategies
255
+ - Common pitfalls to avoid
256
+
257
+ ## 🧪 Testing
258
+
259
+ ```bash
260
+ # Run all tests
261
+ pytest
262
+
263
+ # Run with coverage
264
+ pytest --cov=src --cov-report=html
265
+
266
+ # Run specific test file
267
+ pytest tests/test_workflow.py
268
+
269
+ # Verbose output
270
+ pytest -v
271
+ ```
272
+
273
+ ## Project Structure
274
+
275
+ ```
276
+ loom/
277
+ ├── src/
278
+ │ ├── common/ # Shared utilities
279
+ │ ├── core/ # Core engine (context, engine, runner, worker)
280
+ │ ├── database/ # Database layer
281
+ │ ├── decorators/ # @workflow, @step, @activity
282
+ │ ├── lib/ # Utilities and progress tracking
283
+ │ ├── migrations/ # Database migrations
284
+ │ └── schemas/ # Type definitions
285
+ ├── tests/ # Test suite
286
+ ├── examples/ # Example workflows
287
+ ├── loom.py # Main package interface
288
+ └── pyproject.toml # Package configuration
289
+ ```
290
+
291
+ ## Configuration
292
+
293
+ Loom uses SQLite by default for simplicity. For production:
294
+
295
+ - Consider PostgreSQL/MySQL for scalability
296
+ - Implement connection pooling
297
+ - Add monitoring and alerting
298
+ - Deploy multiple workers for high availability
299
+
300
+ ## Contributing
301
+
302
+ Contributions welcome! Please ensure:
303
+
304
+ 1. Tests pass: `pytest`
305
+ 2. Code formatted: `black .`
306
+ 3. Type checking: `mypy .`
307
+ 4. Linting: `ruff check .`
308
+
309
+ ## License
310
+
311
+ MIT License - see LICENSE file for details
312
+
313
+ ## Acknowledgments
314
+
315
+ Inspired by:
316
+ - [Temporal](https://temporal.io/) - The workflow orchestration platform
317
+ - [Durable Task Framework](https://github.com/Azure/durabletask) - Microsoft's durable task library
318
+ - [Cadence](https://cadenceworkflow.io/) - Uber's workflow platform
319
+
320
+ ---
321
+
322
+ **Built withpy src`
323
+ 4. Linting: `ruff check src`
324
+
325
+ ## 📝 License
326
+
327
+ MIT License - see LICENSE file for details
328
+
329
+ ## 🙏 Acknowledgments
330
+
331
+ Inspired by:
332
+ - [Temporal](https://temporal.io/) - The workflow orchestration platform
333
+ - [Durable Task Framework](https://github.com/Azure/durabletask) - Microsoft's durable task library
334
+ - [Cadence](https://cadenceworkflow.io/) - Uber's workflow platform
335
+
336
+ ## 📧 Contact
337
+
338
+ For questions and support, please open an issue on GitHub.
339
+
340
+ ---
341
+
342
+ **Built with ❤️ using Python 3.12+**
@@ -0,0 +1,50 @@
1
+ loom_core-0.1.0.dist-info/licenses/LICENSE,sha256=8EpC-clAYRUfJQ92T3iQEIIWYjx2A3Kfk28zOd8lh7I,1095
2
+ src/__init__.py,sha256=BESUSbebsjCFRkELNqdCJ3USyVbnoomCl6IRmsdOfLI,1294
3
+ src/cli/__init__.py,sha256=BI8VfSIB5MF4_D9GxHFJwynNEvosDHReVGvsliS99ho,73
4
+ src/cli/cli.py,sha256=cykYs_CKkJWck4auqDxxns9bgPkVznuN9HWsVgfHAmM,7673
5
+ src/common/activity.py,sha256=DXAKEJw5IgvUNJj8yr3Vu0UfxnBZW_KkKcBt70TnpyU,1078
6
+ src/common/config.py,sha256=NZHW07CzpWCaLv77nhULycmD7_QMHdF-3AsrxDFid4A,273
7
+ src/common/errors.py,sha256=jc7_XS8dUPS8fg5pb7kJaTuIR1e6eKBZyZtbsHW3lgM,1712
8
+ src/common/workflow.py,sha256=YfiS0FBhzEBp71t6YKsqM7aNvklvFatb_h3RbgAormQ,1945
9
+ src/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
+ src/core/compiled.py,sha256=Y2NQDMZVLee65ILgJoK2Ny_OcR1T4LJnOQWQcyg0Z7U,1178
11
+ src/core/context.py,sha256=rVWWSOaAmdVOzKKFh9TwpJVX-4Rm0h7bC76ipEcqVBw,9219
12
+ src/core/engine.py,sha256=rZHl15Qa36zvv0r7XDi2f0NGzXoO6X3uHrKaA-jlax4,4202
13
+ src/core/handle.py,sha256=beOVmJit-gSrk7II4c2KuSubmr5OIPls82_vJ-pI04U,5532
14
+ src/core/logger.py,sha256=4ej95IdHOdBh-y7PQoRFz_H22PJYDXvAioBoId8mOhg,1729
15
+ src/core/runner.py,sha256=pYITY35Q88ItZA4EuSWmNE5sgxL0tExXrm9j5vSaz6o,1718
16
+ src/core/state.py,sha256=jdFzSPanATeiWAkQewwcSDjjVseOyMRUdDfsc-a34mQ,2996
17
+ src/core/worker.py,sha256=jpTtvM1rIToVkG4SwJu1W9Q-eL3bw8b3N8KsxxrRovA,5322
18
+ src/core/workflow.py,sha256=E_A2rI6iaW3liZmVy3X98oxSeBDXMGiQnRZRq3Cp3BA,5755
19
+ src/database/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
+ src/database/db.py,sha256=BtZTNtZ6cXpfvrtdmW8Xb47zoC2NXvVoWVmUILow2eA,23535
21
+ src/decorators/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
+ src/decorators/activity.py,sha256=xt7oeYOKJxhKIEcwWsSVA26c_jk4yQB1PHtbcg3tCFI,4824
23
+ src/decorators/workflow.py,sha256=rBpbnpLfDTTAWdgiERpUPIgNUJpnYJKvBZPmzx-ECcc,1516
24
+ src/lib/progress.py,sha256=Es-BKYVI5xOsC-K6wBi5kUbloYIlh5X_V8sLkU7W9IU,3354
25
+ src/lib/utils.py,sha256=aL4VR-_JXbNLYsJYyFL__JQRAq6NQzBYetvHqMGIgYY,809
26
+ src/migrations/down/001_setup_pragma.sql,sha256=NGUGhNmJaroGe_APkLmp6p4q6-zVEYGKHJE4wJixfgs,280
27
+ src/migrations/down/002_create_workflows.sql,sha256=rQcF30tXrBJbbGkOIlJlVMBJ7SZNQHtJpMjgNmo_-hE,58
28
+ src/migrations/down/003.create_events.sql,sha256=5fpnS9yA6gp5z-dOeg7f-klblJPugrwZ6jgwNrQAGLw,52
29
+ src/migrations/down/004.create_tasks.sql,sha256=vFSGPYQLyWdk7sNTk5jrrq3fHZsw1trcPZAd_eL9kVc,50
30
+ src/migrations/down/005.create_indexes.sql,sha256=aDFXwWWwkyjpGqG9zZHTsQ4XyAhrNxDwjivYpVRf458,148
31
+ src/migrations/down/006_auto_update_triggers.sql,sha256=1lEFZsuYANADENOM6baHSA4ljqiovOSstQXIzw80hUc,108
32
+ src/migrations/down/007_create_logs.sql,sha256=LziyAbGM5OFDa2skhk5XhSeC3yzSOaP3Kh_a2gSAEQQ,26
33
+ src/migrations/up/001_setup_pragma.sql,sha256=MAm4ghbC1CXs9OcAryvL-LnwMy00Igb_Ax5Ik2w0YGE,317
34
+ src/migrations/up/002_create_workflows.sql,sha256=2gSUk4EF7dk3mTz6MHHQ-MA6-A8tvbpI30YzgQ9zLCA,530
35
+ src/migrations/up/003_create_events.sql,sha256=3b5uDBjuNkPom4NWUDlV0Xml4tj7BkHBoksJooC1pFk,388
36
+ src/migrations/up/004_create_tasks.sql,sha256=xLGGDFgb0DrrBkiYUOdQ80z019v5MZE7HoA_6MLpCJg,794
37
+ src/migrations/up/005_create_indexes.sql,sha256=1nZVwoyHJdV7YgwXCOZdWFyV0UCZI_jpjsxHyNO9u90,323
38
+ src/migrations/up/006_auto_update_triggers.sql,sha256=hnsbGu6n5XMFKgVha2A_rw9IVRw9zB3Zw73PGOc2R3Y,447
39
+ src/migrations/up/007_create_logs.sql,sha256=IV7vy9U1mGnN4nAZqLwTCyII9Qeeqzx-b1_sSsk1PO4,345
40
+ src/schemas/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
41
+ src/schemas/activity.py,sha256=0sYvmmsVhDFFPyOHkVm0tajVaAAzoq5wY6-K03nPSos,266
42
+ src/schemas/database.py,sha256=v9JXHWx4G_r1-SJcrCJkcnaI7Zbic-ZxtHnd7ezXrF8,282
43
+ src/schemas/events.py,sha256=Gz-R836nVXNSsp4Y54idhKs_WTvzFPmx5KlA8PunP28,2216
44
+ src/schemas/tasks.py,sha256=DJbLInggIGxI-CfP1kSyK79Bz83e3sZyEKh6C2HE8q4,1341
45
+ src/schemas/workflow.py,sha256=F1cNEJRuEWLjPhGinEZE2T6vwchDC8RuTHmxEIaH6Ls,671
46
+ loom_core-0.1.0.dist-info/METADATA,sha256=xMFFZyf9gfKbwMCCyhKKOq3uxZePKTCJweptoqgpiao,11944
47
+ loom_core-0.1.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
48
+ loom_core-0.1.0.dist-info/entry_points.txt,sha256=CgWbuziOoZ90zDBfSlj8mpMOu3scxAzYN10vnYWn9Gk,41
49
+ loom_core-0.1.0.dist-info/top_level.txt,sha256=74rtVfumQlgAPzR5_2CgYN24MB0XARCg0t-gzk6gTrM,4
50
+ loom_core-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (80.10.2)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ loom = src.cli.cli:cli
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Loom Contributors
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 @@
1
+ src
src/__init__.py ADDED
@@ -0,0 +1,45 @@
1
+ """Loom - Durable workflow orchestration engine for Python.
2
+
3
+ This module provides the main API for creating and managing durable workflows.
4
+
5
+ Example:
6
+ >>> import loom
7
+ >>>
8
+ >>> @loom.activity(name="greet", retry_count=3)
9
+ >>> async def greet(name: str) -> str:
10
+ ... return f"Hello, {name}!"
11
+ >>>
12
+ >>> @loom.workflow(name="GreetingWorkflow", version="1.0.0")
13
+ >>> class GreetingWorkflow(loom.Workflow[dict, dict]):
14
+ ... @loom.step(name="greet_step")
15
+ ... async def greet_step(self, ctx):
16
+ ... result = await ctx.activity(greet, ctx.input["name"])
17
+ ... await ctx.state.set("result", result)
18
+ """
19
+
20
+ from src.core.context import WorkflowContext
21
+ from src.core.runner import run_once
22
+ from src.core.worker import WorkflowWorker, start_worker
23
+ from src.core.workflow import Workflow
24
+ from src.database.db import Database
25
+ from src.decorators.activity import activity
26
+ from src.decorators.workflow import step, workflow
27
+
28
+ __version__ = "0.1.0"
29
+
30
+ __all__ = [
31
+ # Decorators
32
+ "activity",
33
+ "workflow",
34
+ "step",
35
+ # Core classes
36
+ "Workflow",
37
+ "WorkflowContext",
38
+ "Database",
39
+ "WorkflowWorker",
40
+ # Functions
41
+ "start_worker",
42
+ "run_once",
43
+ # Version
44
+ "__version__",
45
+ ]
src/cli/__init__.py ADDED
@@ -0,0 +1,5 @@
1
+ """CLI module for Loom."""
2
+
3
+ from .cli import cli
4
+
5
+ __all__ = ["cli"]