pyworkflow-engine 0.1.7__tar.gz → 0.1.9__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.
Files changed (209) hide show
  1. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/PKG-INFO +7 -4
  2. pyworkflow_engine-0.1.9/docs/concepts/step-context.mdx +364 -0
  3. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/docs/concepts/steps.mdx +3 -3
  4. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/docs/concepts/workflows.mdx +3 -3
  5. pyworkflow_engine-0.1.9/examples/celery/durable/workflows/step_context.py +307 -0
  6. pyworkflow_engine-0.1.9/examples/local/durable/13_step_context.py +221 -0
  7. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyproject.toml +18 -6
  8. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/__init__.py +10 -1
  9. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/celery/tasks.py +272 -24
  10. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/cli/__init__.py +4 -1
  11. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/cli/commands/runs.py +4 -4
  12. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/cli/commands/setup.py +203 -4
  13. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/cli/utils/config_generator.py +76 -3
  14. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/cli/utils/docker_manager.py +232 -0
  15. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/context/__init__.py +13 -0
  16. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/context/base.py +26 -0
  17. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/context/local.py +80 -0
  18. pyworkflow_engine-0.1.9/pyworkflow/context/step_context.py +295 -0
  19. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/core/registry.py +6 -1
  20. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/core/step.py +141 -0
  21. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/core/workflow.py +56 -0
  22. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/engine/events.py +30 -0
  23. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/engine/replay.py +39 -0
  24. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/primitives/child_workflow.py +1 -1
  25. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/runtime/local.py +1 -1
  26. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/storage/__init__.py +14 -0
  27. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/storage/base.py +35 -0
  28. pyworkflow_engine-0.1.9/pyworkflow/storage/cassandra.py +1747 -0
  29. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/storage/config.py +69 -0
  30. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/storage/dynamodb.py +31 -2
  31. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/storage/file.py +28 -0
  32. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/storage/memory.py +18 -0
  33. pyworkflow_engine-0.1.9/pyworkflow/storage/mysql.py +1159 -0
  34. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/storage/postgres.py +27 -2
  35. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/storage/schemas.py +4 -3
  36. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/storage/sqlite.py +25 -2
  37. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow_engine.egg-info/SOURCES.txt +9 -27
  38. pyworkflow_engine-0.1.9/tests/integration/test_cassandra_storage.py +1041 -0
  39. pyworkflow_engine-0.1.9/tests/unit/backends/test_cassandra_storage.py +996 -0
  40. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/tests/unit/backends/test_postgres_storage.py +1 -1
  41. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/tests/unit/backends/test_sqlite_storage.py +1 -1
  42. pyworkflow_engine-0.1.9/tests/unit/test_step_context.py +456 -0
  43. pyworkflow_engine-0.1.7/dashboard/backend/app/__init__.py +0 -1
  44. pyworkflow_engine-0.1.7/dashboard/backend/app/config.py +0 -32
  45. pyworkflow_engine-0.1.7/dashboard/backend/app/controllers/__init__.py +0 -6
  46. pyworkflow_engine-0.1.7/dashboard/backend/app/controllers/run_controller.py +0 -86
  47. pyworkflow_engine-0.1.7/dashboard/backend/app/controllers/workflow_controller.py +0 -33
  48. pyworkflow_engine-0.1.7/dashboard/backend/app/dependencies/__init__.py +0 -5
  49. pyworkflow_engine-0.1.7/dashboard/backend/app/dependencies/storage.py +0 -50
  50. pyworkflow_engine-0.1.7/dashboard/backend/app/repositories/__init__.py +0 -6
  51. pyworkflow_engine-0.1.7/dashboard/backend/app/repositories/run_repository.py +0 -80
  52. pyworkflow_engine-0.1.7/dashboard/backend/app/repositories/workflow_repository.py +0 -27
  53. pyworkflow_engine-0.1.7/dashboard/backend/app/rest/__init__.py +0 -8
  54. pyworkflow_engine-0.1.7/dashboard/backend/app/rest/v1/__init__.py +0 -12
  55. pyworkflow_engine-0.1.7/dashboard/backend/app/rest/v1/health.py +0 -33
  56. pyworkflow_engine-0.1.7/dashboard/backend/app/rest/v1/runs.py +0 -133
  57. pyworkflow_engine-0.1.7/dashboard/backend/app/rest/v1/workflows.py +0 -41
  58. pyworkflow_engine-0.1.7/dashboard/backend/app/schemas/__init__.py +0 -23
  59. pyworkflow_engine-0.1.7/dashboard/backend/app/schemas/common.py +0 -16
  60. pyworkflow_engine-0.1.7/dashboard/backend/app/schemas/event.py +0 -24
  61. pyworkflow_engine-0.1.7/dashboard/backend/app/schemas/hook.py +0 -25
  62. pyworkflow_engine-0.1.7/dashboard/backend/app/schemas/run.py +0 -54
  63. pyworkflow_engine-0.1.7/dashboard/backend/app/schemas/step.py +0 -28
  64. pyworkflow_engine-0.1.7/dashboard/backend/app/schemas/workflow.py +0 -31
  65. pyworkflow_engine-0.1.7/dashboard/backend/app/server.py +0 -87
  66. pyworkflow_engine-0.1.7/dashboard/backend/app/services/__init__.py +0 -6
  67. pyworkflow_engine-0.1.7/dashboard/backend/app/services/run_service.py +0 -240
  68. pyworkflow_engine-0.1.7/dashboard/backend/app/services/workflow_service.py +0 -155
  69. pyworkflow_engine-0.1.7/dashboard/backend/main.py +0 -18
  70. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/CLAUDE.md +0 -0
  71. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/DISTRIBUTED.md +0 -0
  72. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/LICENSE +0 -0
  73. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/MANIFEST.in +0 -0
  74. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/README.md +0 -0
  75. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/RELEASING.md +0 -0
  76. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/docs/concepts/cancellation.mdx +0 -0
  77. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/docs/concepts/continue-as-new.mdx +0 -0
  78. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/docs/concepts/events.mdx +0 -0
  79. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/docs/concepts/fault-tolerance.mdx +0 -0
  80. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/docs/concepts/hooks.mdx +0 -0
  81. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/docs/concepts/limitations.mdx +0 -0
  82. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/docs/concepts/schedules.mdx +0 -0
  83. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/docs/concepts/sleep.mdx +0 -0
  84. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/docs/guides/cli.mdx +0 -0
  85. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/docs/guides/configuration.mdx +0 -0
  86. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/docs/introduction.mdx +0 -0
  87. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/docs/quickstart.mdx +0 -0
  88. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/examples/__init__.py +0 -0
  89. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/examples/celery/__init__.py +0 -0
  90. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/examples/celery/durable/docker-compose.yml +0 -0
  91. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/examples/celery/durable/pyworkflow.config.yaml +0 -0
  92. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/examples/celery/durable/workflows/__init__.py +0 -0
  93. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/examples/celery/durable/workflows/basic.py +0 -0
  94. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/examples/celery/durable/workflows/batch_processing.py +0 -0
  95. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/examples/celery/durable/workflows/cancellation.py +0 -0
  96. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/examples/celery/durable/workflows/child_workflow_patterns.py +0 -0
  97. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/examples/celery/durable/workflows/child_workflows.py +0 -0
  98. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/examples/celery/durable/workflows/continue_as_new.py +0 -0
  99. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/examples/celery/durable/workflows/fault_tolerance.py +0 -0
  100. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/examples/celery/durable/workflows/hooks.py +0 -0
  101. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/examples/celery/durable/workflows/idempotency.py +0 -0
  102. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/examples/celery/durable/workflows/long_running.py +0 -0
  103. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/examples/celery/durable/workflows/retries.py +0 -0
  104. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/examples/celery/durable/workflows/schedules.py +0 -0
  105. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/examples/celery/transient/01_basic_workflow.py +0 -0
  106. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/examples/celery/transient/02_fault_tolerance.py +0 -0
  107. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/examples/celery/transient/__init__.py +0 -0
  108. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/examples/celery/transient/pyworkflow.config.yaml +0 -0
  109. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/examples/local/__init__.py +0 -0
  110. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/examples/local/durable/01_basic_workflow.py +0 -0
  111. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/examples/local/durable/02_file_storage.py +0 -0
  112. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/examples/local/durable/03_retries.py +0 -0
  113. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/examples/local/durable/04_long_running.py +0 -0
  114. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/examples/local/durable/05_event_log.py +0 -0
  115. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/examples/local/durable/06_idempotency.py +0 -0
  116. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/examples/local/durable/07_hooks.py +0 -0
  117. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/examples/local/durable/08_cancellation.py +0 -0
  118. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/examples/local/durable/09_child_workflows.py +0 -0
  119. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/examples/local/durable/10_child_workflow_patterns.py +0 -0
  120. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/examples/local/durable/11_continue_as_new.py +0 -0
  121. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/examples/local/durable/12_schedules.py +0 -0
  122. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/examples/local/durable/__init__.py +0 -0
  123. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/examples/local/transient/01_quick_tasks.py +0 -0
  124. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/examples/local/transient/02_retries.py +0 -0
  125. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/examples/local/transient/03_sleep.py +0 -0
  126. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/examples/local/transient/__init__.py +0 -0
  127. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/aws/__init__.py +0 -0
  128. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/aws/context.py +0 -0
  129. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/aws/handler.py +0 -0
  130. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/aws/testing.py +0 -0
  131. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/celery/__init__.py +0 -0
  132. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/celery/app.py +0 -0
  133. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/celery/scheduler.py +0 -0
  134. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/cli/__main__.py +0 -0
  135. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/cli/commands/__init__.py +0 -0
  136. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/cli/commands/hooks.py +0 -0
  137. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/cli/commands/quickstart.py +0 -0
  138. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/cli/commands/scheduler.py +0 -0
  139. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/cli/commands/schedules.py +0 -0
  140. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/cli/commands/worker.py +0 -0
  141. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/cli/commands/workflows.py +0 -0
  142. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/cli/output/__init__.py +0 -0
  143. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/cli/output/formatters.py +0 -0
  144. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/cli/output/styles.py +0 -0
  145. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/cli/utils/__init__.py +0 -0
  146. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/cli/utils/async_helpers.py +0 -0
  147. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/cli/utils/config.py +0 -0
  148. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/cli/utils/discovery.py +0 -0
  149. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/cli/utils/interactive.py +0 -0
  150. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/cli/utils/storage.py +0 -0
  151. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/config.py +0 -0
  152. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/context/aws.py +0 -0
  153. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/context/mock.py +0 -0
  154. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/core/__init__.py +0 -0
  155. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/core/exceptions.py +0 -0
  156. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/core/scheduled.py +0 -0
  157. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/discovery.py +0 -0
  158. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/engine/__init__.py +0 -0
  159. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/engine/executor.py +0 -0
  160. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/observability/__init__.py +0 -0
  161. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/observability/logging.py +0 -0
  162. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/primitives/__init__.py +0 -0
  163. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/primitives/child_handle.py +0 -0
  164. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/primitives/continue_as_new.py +0 -0
  165. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/primitives/define_hook.py +0 -0
  166. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/primitives/hooks.py +0 -0
  167. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/primitives/resume_hook.py +0 -0
  168. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/primitives/schedule.py +0 -0
  169. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/primitives/shield.py +0 -0
  170. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/primitives/sleep.py +0 -0
  171. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/runtime/__init__.py +0 -0
  172. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/runtime/base.py +0 -0
  173. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/runtime/celery.py +0 -0
  174. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/runtime/factory.py +0 -0
  175. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/scheduler/__init__.py +0 -0
  176. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/scheduler/local.py +0 -0
  177. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/serialization/__init__.py +0 -0
  178. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/serialization/decoder.py +0 -0
  179. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/serialization/encoder.py +0 -0
  180. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/utils/__init__.py +0 -0
  181. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/utils/duration.py +0 -0
  182. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/pyworkflow/utils/schedule.py +0 -0
  183. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/setup.cfg +0 -0
  184. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/tests/examples/__init__.py +0 -0
  185. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/tests/integration/__init__.py +0 -0
  186. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/tests/integration/test_cancellation.py +0 -0
  187. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/tests/integration/test_child_workflows.py +0 -0
  188. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/tests/integration/test_continue_as_new.py +0 -0
  189. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/tests/integration/test_dynamodb_storage.py +0 -0
  190. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/tests/integration/test_fault_tolerance.py +0 -0
  191. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/tests/integration/test_schedule_storage.py +0 -0
  192. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/tests/unit/__init__.py +0 -0
  193. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/tests/unit/backends/__init__.py +0 -0
  194. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/tests/unit/backends/test_dynamodb_storage.py +0 -0
  195. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/tests/unit/conftest.py +0 -0
  196. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/tests/unit/test_cancellation.py +0 -0
  197. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/tests/unit/test_child_workflows.py +0 -0
  198. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/tests/unit/test_continue_as_new.py +0 -0
  199. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/tests/unit/test_event_limits.py +0 -0
  200. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/tests/unit/test_executor.py +0 -0
  201. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/tests/unit/test_fault_tolerance.py +0 -0
  202. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/tests/unit/test_hooks.py +0 -0
  203. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/tests/unit/test_registry.py +0 -0
  204. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/tests/unit/test_replay.py +0 -0
  205. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/tests/unit/test_schedule_schemas.py +0 -0
  206. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/tests/unit/test_schedule_utils.py +0 -0
  207. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/tests/unit/test_scheduled_workflow.py +0 -0
  208. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/tests/unit/test_step.py +0 -0
  209. {pyworkflow_engine-0.1.7 → pyworkflow_engine-0.1.9}/tests/unit/test_workflow.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyworkflow-engine
3
- Version: 0.1.7
3
+ Version: 0.1.9
4
4
  Summary: A Python implementation of durable, event-sourced workflows inspired by Vercel Workflow
5
5
  Author: PyWorkflow Contributors
6
6
  License: MIT
@@ -35,7 +35,6 @@ Requires-Dist: pyyaml>=6.0.0
35
35
  Requires-Dist: croniter>=2.0.0
36
36
  Provides-Extra: redis
37
37
  Requires-Dist: redis>=5.0.0; extra == "redis"
38
- Requires-Dist: celery[redis]<6.0.0,>=5.3.0; extra == "redis"
39
38
  Provides-Extra: sqlite
40
39
  Requires-Dist: aiosqlite>=0.19.0; extra == "sqlite"
41
40
  Provides-Extra: postgres
@@ -44,12 +43,17 @@ Provides-Extra: aws
44
43
  Requires-Dist: aws-durable-execution-sdk-python>=0.1.0; extra == "aws"
45
44
  Provides-Extra: dynamodb
46
45
  Requires-Dist: aiobotocore>=2.5.0; extra == "dynamodb"
46
+ Provides-Extra: cassandra
47
+ Requires-Dist: cassandra-driver>=3.29.0; extra == "cassandra"
48
+ Provides-Extra: mysql
49
+ Requires-Dist: aiomysql>=0.2.0; extra == "mysql"
47
50
  Provides-Extra: all
48
51
  Requires-Dist: redis>=5.0.0; extra == "all"
49
- Requires-Dist: celery[redis]<6.0.0,>=5.3.0; extra == "all"
50
52
  Requires-Dist: aiosqlite>=0.19.0; extra == "all"
51
53
  Requires-Dist: asyncpg>=0.29.0; extra == "all"
54
+ Requires-Dist: aiomysql>=0.2.0; extra == "all"
52
55
  Requires-Dist: aws-durable-execution-sdk-python>=0.1.0; extra == "all"
56
+ Requires-Dist: cassandra-driver>=3.29.0; extra == "all"
53
57
  Provides-Extra: dev
54
58
  Requires-Dist: pytest>=7.4.0; extra == "dev"
55
59
  Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
@@ -66,7 +70,6 @@ Requires-Dist: types-python-dateutil>=2.8.0; extra == "dev"
66
70
  Requires-Dist: types-PyYAML>=6.0.0; extra == "dev"
67
71
  Requires-Dist: flower>=2.0.0; extra == "dev"
68
72
  Requires-Dist: redis>=5.0.0; extra == "dev"
69
- Requires-Dist: celery[redis]<6.0.0,>=5.3.0; extra == "dev"
70
73
  Requires-Dist: aiosqlite>=0.19.0; extra == "dev"
71
74
  Requires-Dist: asyncpg>=0.29.0; extra == "dev"
72
75
  Dynamic: license-file
@@ -0,0 +1,364 @@
1
+ ---
2
+ title: 'Step Context'
3
+ description: 'Share typed, read-only context data between workflows and distributed steps'
4
+ ---
5
+
6
+ ## What is Step Context?
7
+
8
+ Step Context provides a way to share workflow-level data with steps executing on remote Celery workers. Unlike the workflow context which is process-local, Step Context is serialized and passed to workers, making it accessible in distributed step execution.
9
+
10
+ ```python
11
+ from pyworkflow import workflow, step, StepContext, get_step_context, set_step_context
12
+
13
+ class OrderContext(StepContext):
14
+ workspace_id: str = ""
15
+ user_id: str = ""
16
+ order_id: str = ""
17
+
18
+ @workflow(context_class=OrderContext)
19
+ async def process_order(order_id: str, user_id: str):
20
+ # Initialize context in workflow
21
+ ctx = OrderContext(order_id=order_id, user_id=user_id)
22
+ await set_step_context(ctx)
23
+
24
+ # Steps can read the context
25
+ result = await validate_order()
26
+ return result
27
+
28
+ @step()
29
+ async def validate_order():
30
+ ctx = get_step_context() # Read-only access
31
+ print(f"Validating order {ctx.order_id} for user {ctx.user_id}")
32
+ return {"valid": True}
33
+ ```
34
+
35
+ ## Key Characteristics
36
+
37
+ <CardGroup cols={2}>
38
+ <Card title="Type-Safe" icon="shield-check">
39
+ Define typed context fields using Pydantic models with full IDE support.
40
+ </Card>
41
+ <Card title="Read-Only in Steps" icon="lock">
42
+ Context is read-only during step execution to prevent race conditions.
43
+ </Card>
44
+ <Card title="Distributed" icon="server">
45
+ Context is automatically serialized and passed to Celery workers.
46
+ </Card>
47
+ <Card title="Event-Sourced" icon="database">
48
+ Context changes are recorded as events for deterministic replay.
49
+ </Card>
50
+ </CardGroup>
51
+
52
+ ## Why Read-Only in Steps?
53
+
54
+ When steps execute in parallel on different workers, allowing them to modify shared context would cause race conditions:
55
+
56
+ ```
57
+ Worker A: read context → modify → save ─┐
58
+ ├─> Lost update!
59
+ Worker B: read context → modify → save ─┘
60
+ ```
61
+
62
+ By making context read-only in steps, PyWorkflow follows the same pattern used by [Temporal](https://temporal.io) and [Prefect](https://prefect.io) - activities/tasks are stateless, and state mutations happen through return values in the workflow.
63
+
64
+ <Info>
65
+ If you need to update context based on step results, do it in the workflow code after the step returns.
66
+ </Info>
67
+
68
+ ## Defining a Context Class
69
+
70
+ Create a context class by extending `StepContext`:
71
+
72
+ ```python
73
+ from pyworkflow import StepContext
74
+
75
+ class FlowContext(StepContext):
76
+ # Required fields (no default)
77
+ workspace_id: str
78
+
79
+ # Optional fields (with defaults)
80
+ user_id: str = ""
81
+ request_id: str = ""
82
+ tags: list[str] = []
83
+ ```
84
+
85
+ ### Immutable by Design
86
+
87
+ Step Context is immutable (frozen). To update values, use `with_updates()` which creates a new instance:
88
+
89
+ ```python
90
+ ctx = FlowContext(workspace_id="ws-123")
91
+ print(ctx.workspace_id) # "ws-123"
92
+
93
+ # Create new context with updated values
94
+ ctx = ctx.with_updates(user_id="user-456", request_id="req-789")
95
+ print(ctx.user_id) # "user-456"
96
+
97
+ # Original values are preserved
98
+ print(ctx.workspace_id) # "ws-123"
99
+ ```
100
+
101
+ <Warning>
102
+ Direct attribute assignment raises an error:
103
+ ```python
104
+ ctx.user_id = "new-value" # ValidationError!
105
+ ```
106
+ </Warning>
107
+
108
+ ## Using Step Context
109
+
110
+ ### Setting Context (Workflow Only)
111
+
112
+ Use `set_step_context()` to set or update the context. This can only be called from workflow code:
113
+
114
+ ```python
115
+ from pyworkflow import workflow, set_step_context
116
+
117
+ @workflow(context_class=OrderContext)
118
+ async def my_workflow(user_id: str):
119
+ # Initialize context
120
+ ctx = OrderContext(user_id=user_id, workspace_id="ws-123")
121
+ await set_step_context(ctx) # Note: async function
122
+
123
+ # ... execute steps ...
124
+
125
+ # Update context (creates new instance)
126
+ ctx = get_step_context()
127
+ ctx = ctx.with_updates(order_id="order-456")
128
+ await set_step_context(ctx)
129
+ ```
130
+
131
+ <Note>
132
+ `set_step_context()` is an async function because it persists the context to storage and records a `CONTEXT_UPDATED` event.
133
+ </Note>
134
+
135
+ ### Reading Context (Workflow and Steps)
136
+
137
+ Use `get_step_context()` to access the current context from anywhere:
138
+
139
+ ```python
140
+ from pyworkflow import step, get_step_context
141
+
142
+ @step()
143
+ async def send_notification():
144
+ ctx = get_step_context()
145
+
146
+ await notify_user(
147
+ user_id=ctx.user_id,
148
+ workspace_id=ctx.workspace_id,
149
+ message=f"Order {ctx.order_id} processed"
150
+ )
151
+ ```
152
+
153
+ ### Checking Context Availability
154
+
155
+ Use `has_step_context()` to check if context is available:
156
+
157
+ ```python
158
+ from pyworkflow import has_step_context, get_step_context
159
+
160
+ @step()
161
+ async def optional_logging():
162
+ if has_step_context():
163
+ ctx = get_step_context()
164
+ logger.info(f"Processing in workspace {ctx.workspace_id}")
165
+ ```
166
+
167
+ ## Read-Only Enforcement
168
+
169
+ Attempting to set context from within a step raises a `RuntimeError`:
170
+
171
+ ```python
172
+ @step()
173
+ async def my_step():
174
+ ctx = get_step_context()
175
+
176
+ # This works - reading context
177
+ print(ctx.workspace_id)
178
+
179
+ # This raises RuntimeError!
180
+ new_ctx = ctx.with_updates(workspace_id="new-ws")
181
+ await set_step_context(new_ctx) # RuntimeError: Cannot modify step context within a step
182
+ ```
183
+
184
+ To update context based on step results, return data from the step and update in the workflow:
185
+
186
+ ```python
187
+ @workflow(context_class=OrderContext)
188
+ async def process_order(order_id: str):
189
+ ctx = OrderContext(order_id=order_id)
190
+ await set_step_context(ctx)
191
+
192
+ # Step returns data instead of modifying context
193
+ validation_result = await validate_order()
194
+
195
+ # Update context in workflow based on step result
196
+ if validation_result["needs_review"]:
197
+ ctx = get_step_context()
198
+ ctx = ctx.with_updates(status="pending_review")
199
+ await set_step_context(ctx)
200
+ ```
201
+
202
+ ## Context Persistence and Replay
203
+
204
+ Step Context is event-sourced for durability:
205
+
206
+ 1. **Persistence**: When you call `set_step_context()`, the context is:
207
+ - Stored in the `WorkflowRun.context` field
208
+ - Recorded as a `CONTEXT_UPDATED` event
209
+
210
+ 2. **Replay**: When a workflow resumes after suspension:
211
+ - Context is restored from the event log
212
+ - Steps receive the same context they had during original execution
213
+
214
+ ```python
215
+ @workflow(context_class=OrderContext)
216
+ async def durable_workflow(order_id: str):
217
+ ctx = OrderContext(order_id=order_id)
218
+ await set_step_context(ctx) # Persisted to storage
219
+
220
+ await some_step()
221
+
222
+ await sleep("1h") # Workflow suspends
223
+
224
+ # After 1 hour, workflow resumes
225
+ # Context is automatically restored from events
226
+ ctx = get_step_context()
227
+ print(ctx.order_id) # Still "order_id" - restored from replay
228
+ ```
229
+
230
+ ## Complex Context Types
231
+
232
+ Step Context supports complex nested types:
233
+
234
+ ```python
235
+ from pydantic import BaseModel
236
+
237
+ class Address(BaseModel):
238
+ street: str
239
+ city: str
240
+ country: str
241
+
242
+ model_config = {"frozen": True}
243
+
244
+ class CustomerContext(StepContext):
245
+ customer_id: str
246
+ email: str = ""
247
+ shipping_address: Address | None = None
248
+ metadata: dict[str, str] = {}
249
+
250
+ @workflow(context_class=CustomerContext)
251
+ async def ship_order(customer_id: str, address: dict):
252
+ ctx = CustomerContext(
253
+ customer_id=customer_id,
254
+ shipping_address=Address(**address)
255
+ )
256
+ await set_step_context(ctx)
257
+ ```
258
+
259
+ <Warning>
260
+ All context fields must be JSON-serializable. Avoid storing non-serializable objects like database connections or file handles.
261
+ </Warning>
262
+
263
+ ## Best Practices
264
+
265
+ <AccordionGroup>
266
+ <Accordion title="Keep context small">
267
+ Store only essential cross-cutting data like IDs, user info, and configuration. Don't use context as a data store - pass large data as step arguments instead.
268
+
269
+ ```python
270
+ # Good - small, essential data
271
+ class GoodContext(StepContext):
272
+ workspace_id: str
273
+ user_id: str
274
+ request_id: str
275
+
276
+ # Bad - too much data
277
+ class BadContext(StepContext):
278
+ workspace_id: str
279
+ user_data: dict # Could be large
280
+ all_orders: list[dict] # Definitely too large
281
+ ```
282
+ </Accordion>
283
+
284
+ <Accordion title="Use context for cross-cutting concerns">
285
+ Step Context is ideal for data needed by many steps: auth info, workspace IDs, correlation IDs, feature flags.
286
+
287
+ ```python
288
+ class RequestContext(StepContext):
289
+ workspace_id: str
290
+ user_id: str
291
+ correlation_id: str # For distributed tracing
292
+ feature_flags: dict[str, bool] = {}
293
+ ```
294
+ </Accordion>
295
+
296
+ <Accordion title="Initialize context early">
297
+ Set up context at the beginning of your workflow before calling any steps.
298
+
299
+ ```python
300
+ @workflow(context_class=MyContext)
301
+ async def my_workflow(workspace_id: str, user_id: str):
302
+ # Initialize context first
303
+ ctx = MyContext(workspace_id=workspace_id, user_id=user_id)
304
+ await set_step_context(ctx)
305
+
306
+ # Now call steps
307
+ await step_one()
308
+ await step_two()
309
+ ```
310
+ </Accordion>
311
+
312
+ <Accordion title="Don't store secrets in context">
313
+ Context is persisted to storage. Use secret managers or environment variables for sensitive data.
314
+
315
+ ```python
316
+ # Bad - secrets in context
317
+ class BadContext(StepContext):
318
+ api_key: str # Don't do this!
319
+
320
+ # Good - reference to secret, not the secret itself
321
+ class GoodContext(StepContext):
322
+ secret_name: str # Reference to secret in vault
323
+
324
+ @step()
325
+ async def call_api():
326
+ ctx = get_step_context()
327
+ api_key = await secret_manager.get(ctx.secret_name)
328
+ ```
329
+ </Accordion>
330
+ </AccordionGroup>
331
+
332
+ ## API Reference
333
+
334
+ | Function | Description |
335
+ |----------|-------------|
336
+ | `StepContext` | Base class for user-defined context |
337
+ | `get_step_context()` | Get current context (raises if not set) |
338
+ | `set_step_context(ctx)` | Set context (async, workflow only) |
339
+ | `has_step_context()` | Check if context is available |
340
+
341
+ ### StepContext Methods
342
+
343
+ | Method | Description |
344
+ |--------|-------------|
345
+ | `with_updates(**kwargs)` | Create new context with updated fields |
346
+ | `to_dict()` | Serialize context to dictionary |
347
+ | `from_dict(data)` | Deserialize context from dictionary |
348
+
349
+ ## Next Steps
350
+
351
+ <CardGroup cols={2}>
352
+ <Card title="Steps" icon="stairs" href="/concepts/steps">
353
+ Learn about steps - the building blocks that use context.
354
+ </Card>
355
+ <Card title="Events" icon="timeline" href="/concepts/events">
356
+ Understand how context changes are event-sourced.
357
+ </Card>
358
+ <Card title="Fault Tolerance" icon="shield-check" href="/concepts/fault-tolerance">
359
+ See how context survives crashes and restarts.
360
+ </Card>
361
+ <Card title="Configuration" icon="gear" href="/guides/configuration">
362
+ Configure storage backends for context persistence.
363
+ </Card>
364
+ </CardGroup>
@@ -292,10 +292,10 @@ async def load_dashboard(user_id: str):
292
292
  ## Next Steps
293
293
 
294
294
  <CardGroup cols={2}>
295
+ <Card title="Step Context" icon="database" href="/concepts/step-context">
296
+ Share typed context data between workflows and distributed steps.
297
+ </Card>
295
298
  <Card title="Events" icon="timeline" href="/concepts/events">
296
299
  Learn how event sourcing enables durability and replay.
297
300
  </Card>
298
- <Card title="Error Handling" icon="shield-check" href="/guides/error-handling">
299
- Deep dive into retry strategies and error handling.
300
- </Card>
301
301
  </CardGroup>
@@ -243,12 +243,12 @@ async def my_workflow():
243
243
  <Card title="Steps" icon="stairs" href="/concepts/steps">
244
244
  Learn about steps - the building blocks of workflows.
245
245
  </Card>
246
+ <Card title="Step Context" icon="database" href="/concepts/step-context">
247
+ Share typed context data with distributed steps.
248
+ </Card>
246
249
  <Card title="Schedules" icon="calendar" href="/concepts/schedules">
247
250
  Automatically run workflows on cron, interval, or calendar schedules.
248
251
  </Card>
249
- <Card title="Sleep" icon="clock" href="/concepts/sleep">
250
- Pause workflows for any duration without consuming resources.
251
- </Card>
252
252
  <Card title="Fault Tolerance" icon="shield-check" href="/concepts/fault-tolerance">
253
253
  Configure auto recovery from worker crashes.
254
254
  </Card>