conductor-python 1.1.7__tar.gz → 1.1.8__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 (208) hide show
  1. conductor_python-1.1.8/PKG-INFO +956 -0
  2. conductor_python-1.1.8/README.md +929 -0
  3. conductor_python-1.1.8/src/conductor/client/http/api/schema_resource_api.py +485 -0
  4. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/__init__.py +2 -0
  5. conductor_python-1.1.8/src/conductor/client/http/models/schema_def.py +186 -0
  6. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/task_def.py +62 -3
  7. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/workflow_def.py +61 -5
  8. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/workflow_task.py +1 -1
  9. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/orkes/orkes_base_client.py +2 -0
  10. conductor_python-1.1.8/src/conductor/client/orkes/orkes_schema_client.py +27 -0
  11. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/orkes_clients.py +6 -1
  12. conductor_python-1.1.8/src/conductor/client/schema_client.py +51 -0
  13. conductor_python-1.1.8/src/conductor_python.egg-info/PKG-INFO +956 -0
  14. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor_python.egg-info/SOURCES.txt +4 -0
  15. conductor_python-1.1.7/PKG-INFO +0 -271
  16. conductor_python-1.1.7/README.md +0 -244
  17. conductor_python-1.1.7/src/conductor_python.egg-info/PKG-INFO +0 -271
  18. {conductor_python-1.1.7 → conductor_python-1.1.8}/LICENSE +0 -0
  19. {conductor_python-1.1.7 → conductor_python-1.1.8}/setup.cfg +0 -0
  20. {conductor_python-1.1.7 → conductor_python-1.1.8}/setup.py +0 -0
  21. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/__init__.py +0 -0
  22. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/__init__.py +0 -0
  23. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/ai/__init__.py +0 -0
  24. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/ai/configuration.py +0 -0
  25. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/ai/integrations.py +0 -0
  26. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/ai/orchestrator.py +0 -0
  27. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/authorization_client.py +0 -0
  28. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/automator/__init__.py +0 -0
  29. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/automator/task_handler.py +0 -0
  30. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/automator/task_runner.py +0 -0
  31. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/automator/utils.py +0 -0
  32. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/configuration/__init__.py +0 -0
  33. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/configuration/configuration.py +0 -0
  34. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/configuration/settings/__init__.py +0 -0
  35. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/configuration/settings/authentication_settings.py +0 -0
  36. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/configuration/settings/metrics_settings.py +0 -0
  37. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/event/__init__.py +0 -0
  38. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/event/event_client.py +0 -0
  39. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/event/queue/__init__.py +0 -0
  40. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/event/queue/kafka_queue_configuration.py +0 -0
  41. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/event/queue/queue_configuration.py +0 -0
  42. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/event/queue/queue_worker_configuration.py +0 -0
  43. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/exceptions/__init__.py +0 -0
  44. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/exceptions/api_error.py +0 -0
  45. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/exceptions/api_exception_handler.py +0 -0
  46. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/helpers/__init__.py +0 -0
  47. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/helpers/helper.py +0 -0
  48. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/__init__.py +0 -0
  49. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/api/__init__.py +0 -0
  50. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/api/application_resource_api.py +0 -0
  51. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/api/authorization_resource_api.py +0 -0
  52. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/api/event_resource_api.py +0 -0
  53. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/api/group_resource_api.py +0 -0
  54. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/api/integration_resource_api.py +0 -0
  55. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/api/metadata_resource_api.py +0 -0
  56. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/api/prompt_resource_api.py +0 -0
  57. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/api/scheduler_resource_api.py +0 -0
  58. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/api/secret_resource_api.py +0 -0
  59. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/api/task_resource_api.py +0 -0
  60. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/api/token_resource_api.py +0 -0
  61. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/api/user_resource_api.py +0 -0
  62. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/api/workflow_bulk_resource_api.py +0 -0
  63. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/api/workflow_resource_api.py +0 -0
  64. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/api_client.py +0 -0
  65. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/action.py +0 -0
  66. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/authorization_request.py +0 -0
  67. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/bulk_response.py +0 -0
  68. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/conductor_application.py +0 -0
  69. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/conductor_user.py +0 -0
  70. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/correlation_ids_search_request.py +0 -0
  71. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/create_or_update_application_request.py +0 -0
  72. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/event_handler.py +0 -0
  73. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/external_storage_location.py +0 -0
  74. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/generate_token_request.py +0 -0
  75. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/group.py +0 -0
  76. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/health.py +0 -0
  77. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/health_check_status.py +0 -0
  78. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/integration.py +0 -0
  79. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/integration_api.py +0 -0
  80. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/integration_api_update.py +0 -0
  81. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/integration_def.py +0 -0
  82. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/integration_update.py +0 -0
  83. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/permission.py +0 -0
  84. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/poll_data.py +0 -0
  85. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/prompt_template.py +0 -0
  86. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/prompt_test_request.py +0 -0
  87. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/rate_limit.py +0 -0
  88. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/rerun_workflow_request.py +0 -0
  89. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/response.py +0 -0
  90. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/role.py +0 -0
  91. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/save_schedule_request.py +0 -0
  92. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/scrollable_search_result_workflow_summary.py +0 -0
  93. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/search_result_task.py +0 -0
  94. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/search_result_task_summary.py +0 -0
  95. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/search_result_workflow.py +0 -0
  96. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/search_result_workflow_schedule_execution_model.py +0 -0
  97. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/search_result_workflow_summary.py +0 -0
  98. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/skip_task_request.py +0 -0
  99. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/start_workflow.py +0 -0
  100. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/start_workflow_request.py +0 -0
  101. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/state_change_event.py +0 -0
  102. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/sub_workflow_params.py +0 -0
  103. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/subject_ref.py +0 -0
  104. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/tag_object.py +0 -0
  105. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/tag_string.py +0 -0
  106. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/target_ref.py +0 -0
  107. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/task.py +0 -0
  108. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/task_details.py +0 -0
  109. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/task_exec_log.py +0 -0
  110. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/task_result.py +0 -0
  111. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/task_result_status.py +0 -0
  112. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/task_summary.py +0 -0
  113. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/token.py +0 -0
  114. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/upsert_group_request.py +0 -0
  115. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/upsert_user_request.py +0 -0
  116. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/workflow.py +0 -0
  117. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/workflow_run.py +0 -0
  118. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/workflow_schedule.py +0 -0
  119. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/workflow_schedule_execution_model.py +0 -0
  120. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/workflow_state_update.py +0 -0
  121. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/workflow_status.py +0 -0
  122. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/workflow_summary.py +0 -0
  123. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/workflow_tag.py +0 -0
  124. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/models/workflow_test_request.py +0 -0
  125. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/rest.py +0 -0
  126. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/http/thread.py +0 -0
  127. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/integration_client.py +0 -0
  128. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/metadata_client.py +0 -0
  129. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/orkes/__init__.py +0 -0
  130. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/orkes/api/__init__.py +0 -0
  131. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/orkes/api/tags_api.py +0 -0
  132. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/orkes/models/__init__.py +0 -0
  133. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/orkes/models/access_key.py +0 -0
  134. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/orkes/models/access_key_status.py +0 -0
  135. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/orkes/models/access_type.py +0 -0
  136. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/orkes/models/created_access_key.py +0 -0
  137. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/orkes/models/granted_permission.py +0 -0
  138. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/orkes/models/metadata_tag.py +0 -0
  139. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/orkes/models/ratelimit_tag.py +0 -0
  140. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/orkes/orkes_authorization_client.py +0 -0
  141. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/orkes/orkes_integration_client.py +0 -0
  142. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/orkes/orkes_metadata_client.py +0 -0
  143. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/orkes/orkes_prompt_client.py +0 -0
  144. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/orkes/orkes_scheduler_client.py +0 -0
  145. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/orkes/orkes_secret_client.py +0 -0
  146. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/orkes/orkes_task_client.py +0 -0
  147. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/orkes/orkes_workflow_client.py +0 -0
  148. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/prompt_client.py +0 -0
  149. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/scheduler_client.py +0 -0
  150. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/secret_client.py +0 -0
  151. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/task_client.py +0 -0
  152. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/telemetry/__init__.py +0 -0
  153. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/telemetry/metrics_collector.py +0 -0
  154. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/telemetry/model/__init__.py +0 -0
  155. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/telemetry/model/metric_documentation.py +0 -0
  156. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/telemetry/model/metric_label.py +0 -0
  157. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/telemetry/model/metric_name.py +0 -0
  158. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/worker/__init__.py +0 -0
  159. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/worker/exception.py +0 -0
  160. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/worker/worker.py +0 -0
  161. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/worker/worker_interface.py +0 -0
  162. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/worker/worker_task.py +0 -0
  163. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/workflow/__init__.py +0 -0
  164. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/workflow/conductor_workflow.py +0 -0
  165. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/workflow/executor/__init__.py +0 -0
  166. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/workflow/executor/workflow_executor.py +0 -0
  167. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/workflow/task/__init__.py +0 -0
  168. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/workflow/task/do_while_task.py +0 -0
  169. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/workflow/task/dynamic_fork_task.py +0 -0
  170. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/workflow/task/dynamic_task.py +0 -0
  171. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/workflow/task/event_task.py +0 -0
  172. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/workflow/task/fork_task.py +0 -0
  173. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/workflow/task/get_document.py +0 -0
  174. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/workflow/task/http_poll_task.py +0 -0
  175. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/workflow/task/http_task.py +0 -0
  176. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/workflow/task/human_task.py +0 -0
  177. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/workflow/task/inline.py +0 -0
  178. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/workflow/task/javascript_task.py +0 -0
  179. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/workflow/task/join_task.py +0 -0
  180. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/workflow/task/json_jq_task.py +0 -0
  181. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/workflow/task/kafka_publish.py +0 -0
  182. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/workflow/task/kafka_publish_input.py +0 -0
  183. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/workflow/task/llm_tasks/__init__.py +0 -0
  184. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/workflow/task/llm_tasks/llm_chat_complete.py +0 -0
  185. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/workflow/task/llm_tasks/llm_generate_embeddings.py +0 -0
  186. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/workflow/task/llm_tasks/llm_index_documents.py +0 -0
  187. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/workflow/task/llm_tasks/llm_index_text.py +0 -0
  188. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/workflow/task/llm_tasks/llm_query_embeddings.py +0 -0
  189. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/workflow/task/llm_tasks/llm_search_index.py +0 -0
  190. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/workflow/task/llm_tasks/llm_text_complete.py +0 -0
  191. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/workflow/task/llm_tasks/utils/__init__.py +0 -0
  192. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/workflow/task/llm_tasks/utils/embedding_model.py +0 -0
  193. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/workflow/task/llm_tasks/utils/prompt.py +0 -0
  194. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/workflow/task/set_variable_task.py +0 -0
  195. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/workflow/task/simple_task.py +0 -0
  196. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/workflow/task/start_workflow_task.py +0 -0
  197. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/workflow/task/sub_workflow_task.py +0 -0
  198. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/workflow/task/switch_task.py +0 -0
  199. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/workflow/task/task.py +0 -0
  200. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/workflow/task/task_type.py +0 -0
  201. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/workflow/task/terminate_task.py +0 -0
  202. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/workflow/task/timeout_policy.py +0 -0
  203. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/workflow/task/wait_for_webhook_task.py +0 -0
  204. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/workflow/task/wait_task.py +0 -0
  205. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor/client/workflow_client.py +0 -0
  206. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor_python.egg-info/dependency_links.txt +0 -0
  207. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor_python.egg-info/requires.txt +0 -0
  208. {conductor_python-1.1.7 → conductor_python-1.1.8}/src/conductor_python.egg-info/top_level.txt +0 -0
@@ -0,0 +1,956 @@
1
+ Metadata-Version: 2.1
2
+ Name: conductor-python
3
+ Version: 1.1.8
4
+ Summary: Netflix Conductor Python SDK
5
+ Home-page: https://github.com/conductor-sdk/conductor-python
6
+ Author: Orkes
7
+ Author-email: developers@orkes.io
8
+ Classifier: Development Status :: 5 - Production/Stable
9
+ Classifier: Intended Audience :: Developers
10
+ Classifier: Intended Audience :: System Administrators
11
+ Classifier: License :: OSI Approved :: Apache Software License
12
+ Classifier: Operating System :: OS Independent
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
15
+ Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
16
+ Requires-Python: >=3.6
17
+ Description-Content-Type: text/markdown
18
+ License-File: LICENSE
19
+ Requires-Dist: certifi>=14.05.14
20
+ Requires-Dist: prometheus-client>=0.13.1
21
+ Requires-Dist: six>=1.10
22
+ Requires-Dist: requests>=2.31.0
23
+ Requires-Dist: typing-extensions>=4.2.0
24
+ Requires-Dist: astor>=0.8.1
25
+ Requires-Dist: shortuuid>=1.0.11
26
+ Requires-Dist: dacite>=1.8.1
27
+
28
+ # Conductor OSS Python SDK
29
+
30
+ Python SDK for working with https://github.com/conductor-oss/conductor.
31
+
32
+ [Conductor](https://www.conductor-oss.org/) is the leading open-source orchestration platform allowing developers to build highly scalable distributed applications.
33
+
34
+ Check out the [official documentation for Conductor](https://orkes.io/content).
35
+
36
+ ## ⭐ Conductor OSS
37
+
38
+ Show support for the Conductor OSS. Please help spread the awareness by starring Conductor repo.
39
+
40
+ [![GitHub stars](https://img.shields.io/github/stars/conductor-oss/conductor.svg?style=social&label=Star&maxAge=)](https://GitHub.com/conductor-oss/conductor/)
41
+
42
+ ## Content
43
+
44
+ <!-- START doctoc generated TOC please keep comment here to allow auto update -->
45
+ <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
46
+
47
+ - [Install Conductor Python SDK](#install-conductor-python-sdk)
48
+ - [Get Conductor Python SDK](#get-conductor-python-sdk)
49
+ - [Hello World Application Using Conductor](#hello-world-application-using-conductor)
50
+ - [Step 1: Create Workflow](#step-1-create-workflow)
51
+ - [Creating Workflows by Code](#creating-workflows-by-code)
52
+ - [(Alternatively) Creating Workflows in JSON](#alternatively-creating-workflows-in-json)
53
+ - [Step 2: Write Task Worker](#step-2-write-task-worker)
54
+ - [Step 3: Write _Hello World_ Application](#step-3-write-_hello-world_-application)
55
+ - [Running Workflows on Conductor Standalone (Installed Locally)](#running-workflows-on-conductor-standalone-installed-locally)
56
+ - [Setup Environment Variable](#setup-environment-variable)
57
+ - [Start Conductor Server](#start-conductor-server)
58
+ - [Execute Hello World Application](#execute-hello-world-application)
59
+ - [Running Workflows on Orkes Conductor](#running-workflows-on-orkes-conductor)
60
+ - [Learn More about Conductor Python SDK](#learn-more-about-conductor-python-sdk)
61
+ - [Create and Run Conductor Workers](#create-and-run-conductor-workers)
62
+ - [Writing Workers](#writing-workers)
63
+ - [Implementing Workers](#implementing-workers)
64
+ - [Managing Workers in Application](#managing-workers-in-application)
65
+ - [Design Principles for Workers](#design-principles-for-workers)
66
+ - [System Task Workers](#system-task-workers)
67
+ - [Wait Task](#wait-task)
68
+ - [Using Code to Create Wait Task](#using-code-to-create-wait-task)
69
+ - [JSON Configuration](#json-configuration)
70
+ - [HTTP Task](#http-task)
71
+ - [Using Code to Create HTTP Task](#using-code-to-create-http-task)
72
+ - [JSON Configuration](#json-configuration-1)
73
+ - [Javascript Executor Task](#javascript-executor-task)
74
+ - [Using Code to Create Inline Task](#using-code-to-create-inline-task)
75
+ - [JSON Configuration](#json-configuration-2)
76
+ - [JSON Processing using JQ](#json-processing-using-jq)
77
+ - [Using Code to Create JSON JQ Transform Task](#using-code-to-create-json-jq-transform-task)
78
+ - [JSON Configuration](#json-configuration-3)
79
+ - [Worker vs. Microservice/HTTP Endpoints](#worker-vs-microservicehttp-endpoints)
80
+ - [Deploying Workers in Production](#deploying-workers-in-production)
81
+ - [Create Conductor Workflows](#create-conductor-workflows)
82
+ - [Conductor Workflows](#conductor-workflows)
83
+ - [Creating Workflows](#creating-workflows)
84
+ - [Execute Dynamic Workflows Using Code](#execute-dynamic-workflows-using-code)
85
+ - [Kitchen-Sink Workflow](#kitchen-sink-workflow)
86
+ - [Executing Workflows](#executing-workflows)
87
+ - [Execute Workflow Asynchronously](#execute-workflow-asynchronously)
88
+ - [Execute Workflow Synchronously](#execute-workflow-synchronously)
89
+ - [Managing Workflow Executions](#managing-workflow-executions)
90
+ - [Get Execution Status](#get-execution-status)
91
+ - [Update Workflow State Variables](#update-workflow-state-variables)
92
+ - [Terminate Running Workflows](#terminate-running-workflows)
93
+ - [Retry Failed Workflows](#retry-failed-workflows)
94
+ - [Restart Workflows](#restart-workflows)
95
+ - [Rerun Workflow from a Specific Task](#rerun-workflow-from-a-specific-task)
96
+ - [Pause Running Workflow](#pause-running-workflow)
97
+ - [Resume Paused Workflow](#resume-paused-workflow)
98
+ - [Searching for Workflows](#searching-for-workflows)
99
+ - [Handling Failures, Retries and Rate Limits](#handling-failures-retries-and-rate-limits)
100
+ - [Retries](#retries)
101
+ - [Rate Limits](#rate-limits)
102
+ - [Task Registration](#task-registration)
103
+ - [Update Task Definition:](#update-task-definition)
104
+ - [Using Conductor in Your Application](#using-conductor-in-your-application)
105
+ - [Adding Conductor SDK to Your Application](#adding-conductor-sdk-to-your-application)
106
+ - [Testing Workflows](#testing-workflows)
107
+ - [Example Unit Testing Application](#example-unit-testing-application)
108
+ - [Workflow Deployments Using CI/CD](#workflow-deployments-using-cicd)
109
+ - [Versioning Workflows](#versioning-workflows)
110
+
111
+ <!-- END doctoc generated TOC please keep comment here to allow auto update -->
112
+
113
+ ## Install Conductor Python SDK
114
+
115
+ Before installing Conductor Python SDK, it is a good practice to set up a dedicated virtual environment as follows:
116
+
117
+ ```shell
118
+ virtualenv conductor
119
+ source conductor/bin/activate
120
+ ```
121
+
122
+ ### Get Conductor Python SDK
123
+
124
+ The SDK requires Python 3.9+. To install the SDK, use the following command:
125
+
126
+ ```shell
127
+ python3 -m pip install conductor-python
128
+ ```
129
+
130
+ ## Hello World Application Using Conductor
131
+
132
+ In this section, we will create a simple "Hello World" application that executes a "greetings" workflow managed by Conductor.
133
+
134
+ ### Step 1: Create Workflow
135
+
136
+ #### Creating Workflows by Code
137
+
138
+ Create [greetings_workflow.py](examples/helloworld/greetings_workflow.py) with the following:
139
+
140
+ ```python
141
+ from conductor.client.workflow.conductor_workflow import ConductorWorkflow
142
+ from conductor.client.workflow.executor.workflow_executor import WorkflowExecutor
143
+ from greetings_worker import greet
144
+
145
+ def greetings_workflow(workflow_executor: WorkflowExecutor) -> ConductorWorkflow:
146
+ name = 'greetings'
147
+ workflow = ConductorWorkflow(name=name, executor=workflow_executor)
148
+ workflow.version = 1
149
+ workflow >> greet(task_ref_name='greet_ref', name=workflow.input('name'))
150
+ return workflow
151
+
152
+
153
+ ```
154
+
155
+ #### (Alternatively) Creating Workflows in JSON
156
+
157
+ Create `greetings_workflow.json` with the following:
158
+
159
+ ```json
160
+ {
161
+ "name": "greetings",
162
+ "description": "Sample greetings workflow",
163
+ "version": 1,
164
+ "tasks": [
165
+ {
166
+ "name": "greet",
167
+ "taskReferenceName": "greet_ref",
168
+ "type": "SIMPLE",
169
+ "inputParameters": {
170
+ "name": "${workflow.input.name}"
171
+ }
172
+ }
173
+ ],
174
+ "timeoutPolicy": "TIME_OUT_WF",
175
+ "timeoutSeconds": 60
176
+ }
177
+ ```
178
+
179
+ Workflows must be registered to the Conductor server. Use the API to register the greetings workflow from the JSON file above:
180
+ ```shell
181
+ curl -X POST -H "Content-Type:application/json" \
182
+ http://localhost:8080/api/metadata/workflow -d @greetings_workflow.json
183
+ ```
184
+ > [!note]
185
+ > To use the Conductor API, the Conductor server must be up and running (see [Running over Conductor standalone (installed locally)](#running-over-conductor-standalone-installed-locally)).
186
+
187
+ ### Step 2: Write Task Worker
188
+
189
+ Using Python, a worker represents a function with the worker_task decorator. Create [greetings_worker.py](examples/helloworld/greetings_worker.py) file as illustrated below:
190
+
191
+ > [!note]
192
+ > A single workflow can have task workers written in different languages and deployed anywhere, making your workflow polyglot and distributed!
193
+
194
+ ```python
195
+ from conductor.client.worker.worker_task import worker_task
196
+
197
+
198
+ @worker_task(task_definition_name='greet')
199
+ def greet(name: str) -> str:
200
+ return f'Hello {name}'
201
+
202
+ ```
203
+ Now, we are ready to write our main application, which will execute our workflow.
204
+
205
+ ### Step 3: Write _Hello World_ Application
206
+
207
+ Let's add [helloworld.py](examples/helloworld/helloworld.py) with a `main` method:
208
+
209
+ ```python
210
+ from conductor.client.automator.task_handler import TaskHandler
211
+ from conductor.client.configuration.configuration import Configuration
212
+ from conductor.client.workflow.conductor_workflow import ConductorWorkflow
213
+ from conductor.client.workflow.executor.workflow_executor import WorkflowExecutor
214
+ from greetings_workflow import greetings_workflow
215
+
216
+
217
+ def register_workflow(workflow_executor: WorkflowExecutor) -> ConductorWorkflow:
218
+ workflow = greetings_workflow(workflow_executor=workflow_executor)
219
+ workflow.register(True)
220
+ return workflow
221
+
222
+
223
+ def main():
224
+ # The app is connected to http://localhost:8080/api by default
225
+ api_config = Configuration()
226
+
227
+ workflow_executor = WorkflowExecutor(configuration=api_config)
228
+
229
+ # Registering the workflow (Required only when the app is executed the first time)
230
+ workflow = register_workflow(workflow_executor)
231
+
232
+ # Starting the worker polling mechanism
233
+ task_handler = TaskHandler(configuration=api_config)
234
+ task_handler.start_processes()
235
+
236
+ workflow_run = workflow_executor.execute(name=workflow.name, version=workflow.version,
237
+ workflow_input={'name': 'Orkes'})
238
+
239
+ print(f'\nworkflow result: {workflow_run.output["result"]}\n')
240
+ print(f'see the workflow execution here: {api_config.ui_host}/execution/{workflow_run.workflow_id}\n')
241
+ task_handler.stop_processes()
242
+
243
+
244
+ if __name__ == '__main__':
245
+ main()
246
+ ```
247
+ ## Running Workflows on Conductor Standalone (Installed Locally)
248
+
249
+ ### Setup Environment Variable
250
+
251
+ Set the following environment variable to point the SDK to the Conductor Server API endpoint:
252
+
253
+ ```shell
254
+ export CONDUCTOR_SERVER_URL=http://localhost:8080/api
255
+ ```
256
+ ### Start Conductor Server
257
+
258
+ To start the Conductor server in a standalone mode from a Docker image, type the command below:
259
+
260
+ ```shell
261
+ docker run --init -p 8080:8080 -p 5000:5000 conductoross/conductor-standalone:3.15.0
262
+ ```
263
+ To ensure the server has started successfully, open Conductor UI on http://localhost:5000.
264
+
265
+ ### Execute Hello World Application
266
+
267
+ To run the application, type the following command:
268
+
269
+ ```
270
+ python helloworld.py
271
+ ```
272
+
273
+ Now, the workflow is executed, and its execution status can be viewed from Conductor UI (http://localhost:5000).
274
+
275
+ Navigate to the **Executions** tab to view the workflow execution.
276
+
277
+ <img width="1434" alt="Screenshot 2024-03-18 at 12 30 07" src="https://github.com/Srividhya-S-Subramanian/conductor-python-v1/assets/163816773/11e829b6-d46a-4b47-b2cf-0bf524a6ebdc">
278
+
279
+ ## Running Workflows on Orkes Conductor
280
+
281
+ For running the workflow in Orkes Conductor,
282
+
283
+ - Update the Conductor server URL to your cluster name.
284
+
285
+ ```shell
286
+ export CONDUCTOR_SERVER_URL=https://[cluster-name].orkesconductor.io/api
287
+ ```
288
+
289
+ - If you want to run the workflow on the Orkes Conductor Playground, set the Conductor Server variable as follows:
290
+
291
+ ```shell
292
+ export CONDUCTOR_SERVER_URL=https://play.orkes.io/api
293
+ ```
294
+
295
+ - Orkes Conductor requires authentication. [Obtain the key and secret from the Conductor server](https://orkes.io/content/how-to-videos/access-key-and-secret) and set the following environment variables.
296
+
297
+ ```shell
298
+ export CONDUCTOR_AUTH_KEY=your_key
299
+ export CONDUCTOR_AUTH_SECRET=your_key_secret
300
+ ```
301
+
302
+ Run the application and view the execution status from Conductor's UI Console.
303
+
304
+ > [!NOTE]
305
+ > That's it - you just created and executed your first distributed Python app!
306
+
307
+ ## Learn More about Conductor Python SDK
308
+
309
+ There are three main ways you can use Conductor when building durable, resilient, distributed applications.
310
+
311
+ 1. Write service workers that implement business logic to accomplish a specific goal - such as initiating payment transfer, getting user information from the database, etc.
312
+ 2. Create Conductor workflows that implement application state - A typical workflow implements the saga pattern.
313
+ 3. Use Conductor SDK and APIs to manage workflows from your application.
314
+
315
+ ## Create and Run Conductor Workers
316
+
317
+ ## Writing Workers
318
+
319
+ A Workflow task represents a unit of business logic that achieves a specific goal, such as checking inventory, initiating payment transfer, etc. A worker implements a task in the workflow.
320
+
321
+
322
+ ### Implementing Workers
323
+
324
+ The workers can be implemented by writing a simple Python function and annotating the function with the `@worker_task`. Conductor workers are services (similar to microservices) that follow the [Single Responsibility Principle](https://en.wikipedia.org/wiki/Single_responsibility_principle).
325
+
326
+ Workers can be hosted along with the workflow or run in a distributed environment where a single workflow uses workers deployed and running in different machines/VMs/containers. Whether to keep all the workers in the same application or run them as a distributed application is a design and architectural choice. Conductor is well suited for both kinds of scenarios.
327
+
328
+ You can create or convert any existing Python function to a distributed worker by adding `@worker_task` annotation to it. Here is a simple worker that takes `name` as input and returns greetings:
329
+
330
+ ```python
331
+ from conductor.client.worker.worker_task import worker_task
332
+
333
+ @worker_task(task_definition_name='greetings')
334
+ def greetings(name: str) -> str:
335
+ return f'Hello, {name}'
336
+ ```
337
+
338
+ A worker can take inputs which are primitives - `str`, `int`, `float`, `bool` etc. or can be complex data classes.
339
+
340
+ Here is an example worker that uses `dataclass` as part of the worker input.
341
+
342
+ ```python
343
+ from conductor.client.worker.worker_task import worker_task
344
+ from dataclasses import dataclass
345
+
346
+ @dataclass
347
+ class OrderInfo:
348
+ order_id: int
349
+ sku: str
350
+ quantity: int
351
+ sku_price: float
352
+
353
+
354
+ @worker_task(task_definition_name='process_order')
355
+ def process_order(order_info: OrderInfo) -> str:
356
+ return f'order: {order_info.order_id}'
357
+
358
+ ```
359
+
360
+ ### Managing Workers in Application
361
+
362
+ Workers use a polling mechanism (with a long poll) to check for any available tasks from the server periodically. The startup and shutdown of workers are handled by the `conductor.client.automator.task_handler.TaskHandler` class.
363
+
364
+ ```python
365
+ from conductor.client.automator.task_handler import TaskHandler
366
+ from conductor.client.configuration.configuration import Configuration
367
+
368
+ def main():
369
+ # points to http://localhost:8080/api by default
370
+ api_config = Configuration()
371
+
372
+ task_handler = TaskHandler(
373
+ workers=[],
374
+ configuration=api_config,
375
+ scan_for_annotated_workers=True,
376
+ import_modules=['greetings'] # import workers from this module - leave empty if all the workers are in the same module
377
+ )
378
+
379
+ # start worker polling
380
+ task_handler.start_processes()
381
+
382
+ # Call to stop the workers when the application is ready to shutdown
383
+ task_handler.stop_processes()
384
+
385
+
386
+ if __name__ == '__main__':
387
+ main()
388
+
389
+ ```
390
+
391
+ ### Design Principles for Workers
392
+
393
+ Each worker embodies the design pattern and follows certain basic principles:
394
+
395
+ 1. Workers are stateless and do not implement a workflow-specific logic.
396
+ 2. Each worker executes a particular task and produces well-defined output given specific inputs.
397
+ 3. Workers are meant to be idempotent (Should handle cases where the partially executed task, due to timeouts, etc, gets rescheduled).
398
+ 4. Workers do not implement the logic to handle retries, etc., that is taken care of by the Conductor server.
399
+
400
+ #### System Task Workers
401
+
402
+ A system task worker is a pre-built, general-purpose worker in your Conductor server distribution.
403
+
404
+ System tasks automate repeated tasks such as calling an HTTP endpoint, executing lightweight ECMA-compliant javascript code, publishing to an event broker, etc.
405
+
406
+ #### Wait Task
407
+
408
+ > [!tip]
409
+ > Wait is a powerful way to have your system wait for a specific trigger, such as an external event, a particular date/time, or duration, such as 2 hours, without having to manage threads, background processes, or jobs.
410
+
411
+ ##### Using Code to Create Wait Task
412
+
413
+ ```python
414
+ from conductor.client.workflow.task.wait_task import WaitTask
415
+
416
+ # waits for 2 seconds before scheduling the next task
417
+ wait_for_two_sec = WaitTask(task_ref_name='wait_for_2_sec', wait_for_seconds=2)
418
+
419
+ # wait until end of jan
420
+ wait_till_jan = WaitTask(task_ref_name='wait_till_jsn', wait_until='2024-01-31 00:00 UTC')
421
+
422
+ # waits until an API call or an event is triggered
423
+ wait_for_signal = WaitTask(task_ref_name='wait_till_jan_end')
424
+
425
+ ```
426
+ ##### JSON Configuration
427
+
428
+ ```json
429
+ {
430
+ "name": "wait",
431
+ "taskReferenceName": "wait_till_jan_end",
432
+ "type": "WAIT",
433
+ "inputParameters": {
434
+ "until": "2024-01-31 00:00 UTC"
435
+ }
436
+ }
437
+ ```
438
+ #### HTTP Task
439
+
440
+ Make a request to an HTTP(S) endpoint. The task allows for GET, PUT, POST, DELETE, HEAD, and PATCH requests.
441
+
442
+ ##### Using Code to Create HTTP Task
443
+
444
+ ```python
445
+ from conductor.client.workflow.task.http_task import HttpTask
446
+
447
+ HttpTask(task_ref_name='call_remote_api', http_input={
448
+ 'uri': 'https://orkes-api-tester.orkesconductor.com/api'
449
+ })
450
+ ```
451
+
452
+ ##### JSON Configuration
453
+
454
+ ```json
455
+ {
456
+ "name": "http_task",
457
+ "taskReferenceName": "http_task_ref",
458
+ "type" : "HTTP",
459
+ "uri": "https://orkes-api-tester.orkesconductor.com/api",
460
+ "method": "GET"
461
+ }
462
+ ```
463
+
464
+ #### Javascript Executor Task
465
+
466
+ Execute ECMA-compliant Javascript code. It is useful when writing a script for data mapping, calculations, etc.
467
+
468
+ ##### Using Code to Create Inline Task
469
+
470
+ ```python
471
+ from conductor.client.workflow.task.javascript_task import JavascriptTask
472
+
473
+ say_hello_js = """
474
+ function greetings() {
475
+ return {
476
+ "text": "hello " + $.name
477
+ }
478
+ }
479
+ greetings();
480
+ """
481
+
482
+ js = JavascriptTask(task_ref_name='hello_script', script=say_hello_js, bindings={'name': '${workflow.input.name}'})
483
+ ```
484
+ ##### JSON Configuration
485
+
486
+ ```json
487
+ {
488
+ "name": "inline_task",
489
+ "taskReferenceName": "inline_task_ref",
490
+ "type": "INLINE",
491
+ "inputParameters": {
492
+ "expression": " function greetings() {\n return {\n \"text\": \"hello \" + $.name\n }\n }\n greetings();",
493
+ "evaluatorType": "graaljs",
494
+ "name": "${workflow.input.name}"
495
+ }
496
+ }
497
+ ```
498
+
499
+ #### JSON Processing using JQ
500
+
501
+ [Jq](https://jqlang.github.io/jq/) is like sed for JSON data - you can slice, filter, map, and transform structured data with the same ease that sed, awk, grep, and friends let you play with text.
502
+
503
+ ##### Using Code to Create JSON JQ Transform Task
504
+
505
+ ```python
506
+ from conductor.client.workflow.task.json_jq_task import JsonJQTask
507
+
508
+ jq_script = """
509
+ { key3: (.key1.value1 + .key2.value2) }
510
+ """
511
+
512
+ jq = JsonJQTask(task_ref_name='jq_process', script=jq_script)
513
+ ```
514
+ ##### JSON Configuration
515
+
516
+ ```json
517
+ {
518
+ "name": "json_transform_task",
519
+ "taskReferenceName": "json_transform_task_ref",
520
+ "type": "JSON_JQ_TRANSFORM",
521
+ "inputParameters": {
522
+ "key1": "k1",
523
+ "key2": "k2",
524
+ "queryExpression": "{ key3: (.key1.value1 + .key2.value2) }",
525
+ }
526
+ }
527
+ ```
528
+
529
+ ### Worker vs. Microservice/HTTP Endpoints
530
+
531
+ > [!tip]
532
+ > Workers are a lightweight alternative to exposing an HTTP endpoint and orchestrating using HTTP tasks. Using workers is a recommended approach if you do not need to expose the service over HTTP or gRPC endpoints.
533
+
534
+ There are several advantages to this approach:
535
+
536
+ 1. **No need for an API management layer** : Given there are no exposed endpoints and workers are self-load-balancing.
537
+ 2. **Reduced infrastructure footprint** : No need for an API gateway/load balancer.
538
+ 3. All the communication is initiated by workers using polling - avoiding the need to open up any incoming TCP ports.
539
+ 4. Workers **self-regulate** when busy; they only poll as much as they can handle. Backpressure handling is done out of the box.
540
+ 5. Workers can be scaled up/down quickly based on the demand by increasing the number of processes.
541
+
542
+ ### Deploying Workers in Production
543
+
544
+ Conductor workers can run in the cloud-native environment or on-prem and can easily be deployed like any other Python application. Workers can run a containerized environment, VMs, or bare metal like you would deploy your other Python applications.
545
+
546
+ ## Create Conductor Workflows
547
+
548
+ ### Conductor Workflows
549
+
550
+ Workflow can be defined as the collection of tasks and operators that specify the order and execution of the defined tasks. This orchestration occurs in a hybrid ecosystem that encircles serverless functions, microservices, and monolithic applications.
551
+
552
+ This section will dive deeper into creating and executing Conductor workflows using Python SDK.
553
+
554
+
555
+ ### Creating Workflows
556
+
557
+ Conductor lets you create the workflows using either Python or JSON as the configuration.
558
+
559
+ Using Python as code to define and execute workflows lets you build extremely powerful, dynamic workflows and run them on Conductor.
560
+
561
+ When the workflows are relatively static, they can be designed using the Orkes UI (available when using Orkes Conductor) and APIs or SDKs to register and run the workflows.
562
+
563
+ Both the code and configuration approaches are equally powerful and similar in nature to how you treat Infrastructure as Code.
564
+
565
+ #### Execute Dynamic Workflows Using Code
566
+
567
+ For cases where the workflows cannot be created statically ahead of time, Conductor is a powerful dynamic workflow execution platform that lets you create very complex workflows in code and execute them. It is useful when the workflow is unique for each execution.
568
+
569
+ ```python
570
+ from conductor.client.automator.task_handler import TaskHandler
571
+ from conductor.client.configuration.configuration import Configuration
572
+ from conductor.client.orkes_clients import OrkesClients
573
+ from conductor.client.worker.worker_task import worker_task
574
+ from conductor.client.workflow.conductor_workflow import ConductorWorkflow
575
+
576
+ #@worker_task annotation denotes that this is a worker
577
+ @worker_task(task_definition_name='get_user_email')
578
+ def get_user_email(userid: str) -> str:
579
+ return f'{userid}@example.com'
580
+
581
+ #@worker_task annotation denotes that this is a worker
582
+ @worker_task(task_definition_name='send_email')
583
+ def send_email(email: str, subject: str, body: str):
584
+ print(f'sending email to {email} with subject {subject} and body {body}')
585
+
586
+
587
+ def main():
588
+
589
+ # defaults to reading the configuration using following env variables
590
+ # CONDUCTOR_SERVER_URL : conductor server e.g. https://play.orkes.io/api
591
+ # CONDUCTOR_AUTH_KEY : API Authentication Key
592
+ # CONDUCTOR_AUTH_SECRET: API Auth Secret
593
+ api_config = Configuration()
594
+
595
+ task_handler = TaskHandler(configuration=api_config)
596
+ #Start Polling
597
+ task_handler.start_processes()
598
+
599
+ clients = OrkesClients(configuration=api_config)
600
+ workflow_executor = clients.get_workflow_executor()
601
+ workflow = ConductorWorkflow(name='dynamic_workflow', version=1, executor=workflow_executor)
602
+ get_email = get_user_email(task_ref_name='get_user_email_ref', userid=workflow.input('userid'))
603
+ sendmail = send_email(task_ref_name='send_email_ref', email=get_email.output('result'), subject='Hello from Orkes',
604
+ body='Test Email')
605
+ #Order of task execution
606
+ workflow >> get_email >> sendmail
607
+
608
+ # Configure the output of the workflow
609
+ workflow.output_parameters(output_parameters={
610
+ 'email': get_email.output('result')
611
+ })
612
+ #Run the workflow
613
+ result = workflow.execute(workflow_input={'userid': 'user_a'})
614
+ print(f'\nworkflow output: {result.output}\n')
615
+ #Stop Polling
616
+ task_handler.stop_processes()
617
+
618
+
619
+ if __name__ == '__main__':
620
+ main()
621
+
622
+ ```
623
+
624
+ ```shell
625
+ >> python3 dynamic_workflow.py
626
+
627
+ 2024-02-03 19:54:35,700 [32853] conductor.client.automator.task_handler INFO created worker with name=get_user_email and domain=None
628
+ 2024-02-03 19:54:35,781 [32853] conductor.client.automator.task_handler INFO created worker with name=send_email and domain=None
629
+ 2024-02-03 19:54:35,859 [32853] conductor.client.automator.task_handler INFO TaskHandler initialized
630
+ 2024-02-03 19:54:35,859 [32853] conductor.client.automator.task_handler INFO Starting worker processes...
631
+ 2024-02-03 19:54:35,861 [32853] conductor.client.automator.task_runner INFO Polling task get_user_email with domain None with polling interval 0.1
632
+ 2024-02-03 19:54:35,861 [32853] conductor.client.automator.task_handler INFO Started 2 TaskRunner process
633
+ 2024-02-03 19:54:35,862 [32853] conductor.client.automator.task_handler INFO Started all processes
634
+ 2024-02-03 19:54:35,862 [32853] conductor.client.automator.task_runner INFO Polling task send_email with domain None with polling interval 0.1
635
+ sending email to user_a@example.com with subject Hello from Orkes and body Test Email
636
+
637
+ workflow output: {'email': 'user_a@example.com'}
638
+
639
+ 2024-02-03 19:54:36,309 [32853] conductor.client.automator.task_handler INFO Stopped worker processes...
640
+ ```
641
+ See [dynamic_workflow.py](examples/dynamic_workflow.py) for a fully functional example.
642
+
643
+ #### Kitchen-Sink Workflow
644
+
645
+ For a more complex workflow example with all the supported features, see [kitchensink.py](examples/kitchensink.py).
646
+
647
+ ### Executing Workflows
648
+
649
+ The [WorkflowClient](src/conductor/client/workflow_client.py) interface provides all the APIs required to work with workflow executions.
650
+
651
+ ```python
652
+ from conductor.client.configuration.configuration import Configuration
653
+ from conductor.client.orkes_clients import OrkesClients
654
+
655
+ api_config = Configuration()
656
+ clients = OrkesClients(configuration=api_config)
657
+ workflow_client = clients.get_workflow_client()
658
+ ```
659
+ #### Execute Workflow Asynchronously
660
+
661
+ Useful when workflows are long-running.
662
+
663
+ ```python
664
+ from conductor.client.http.models import StartWorkflowRequest
665
+
666
+ request = StartWorkflowRequest()
667
+ request.name = 'hello'
668
+ request.version = 1
669
+ request.input = {'name': 'Orkes'}
670
+ # workflow id is the unique execution id associated with this execution
671
+ workflow_id = workflow_client.start_workflow(request)
672
+ ```
673
+ #### Execute Workflow Synchronously
674
+
675
+ Applicable when workflows complete very quickly - usually under 20-30 seconds.
676
+
677
+ ```python
678
+ from conductor.client.http.models import StartWorkflowRequest
679
+
680
+ request = StartWorkflowRequest()
681
+ request.name = 'hello'
682
+ request.version = 1
683
+ request.input = {'name': 'Orkes'}
684
+
685
+ workflow_run = workflow_client.execute_workflow(
686
+ start_workflow_request=request,
687
+ wait_for_seconds=12)
688
+ ```
689
+
690
+
691
+ ### Managing Workflow Executions
692
+ > [!note]
693
+ > See [workflow_ops.py](examples/workflow_ops.py) for a fully working application that demonstrates working with the workflow executions and sending signals to the workflow to manage its state.
694
+
695
+ Workflows represent the application state. With Conductor, you can query the workflow execution state anytime during its lifecycle. You can also send signals to the workflow that determines the outcome of the workflow state.
696
+
697
+ [WorkflowClient](src/conductor/client/workflow_client.py) is the client interface used to manage workflow executions.
698
+
699
+ ```python
700
+ from conductor.client.configuration.configuration import Configuration
701
+ from conductor.client.orkes_clients import OrkesClients
702
+
703
+ api_config = Configuration()
704
+ clients = OrkesClients(configuration=api_config)
705
+ workflow_client = clients.get_workflow_client()
706
+ ```
707
+
708
+ ### Get Execution Status
709
+
710
+ The following method lets you query the status of the workflow execution given the id. When the `include_tasks` is set, the response also includes all the completed and in-progress tasks.
711
+
712
+ ```python
713
+ get_workflow(workflow_id: str, include_tasks: Optional[bool] = True) -> Workflow
714
+ ```
715
+
716
+ ### Update Workflow State Variables
717
+
718
+ Variables inside a workflow are the equivalent of global variables in a program.
719
+
720
+ ```python
721
+ update_variables(self, workflow_id: str, variables: dict[str, object] = {})
722
+ ```
723
+
724
+ ### Terminate Running Workflows
725
+
726
+ Used to terminate a running workflow. Any pending tasks are canceled, and no further work is scheduled for this workflow upon termination. A failure workflow will be triggered but can be avoided if `trigger_failure_workflow` is set to False.
727
+
728
+ ```python
729
+ terminate_workflow(self, workflow_id: str, reason: Optional[str] = None, trigger_failure_workflow: bool = False)
730
+ ```
731
+
732
+ ### Retry Failed Workflows
733
+
734
+ If the workflow has failed due to one of the task failures after exhausting the retries for the task, the workflow can still be resumed by calling the retry.
735
+
736
+ ```python
737
+ retry_workflow(self, workflow_id: str, resume_subworkflow_tasks: Optional[bool] = False)
738
+ ```
739
+
740
+ When a sub-workflow inside a workflow has failed, there are two options:
741
+
742
+ 1. Re-trigger the sub-workflow from the start (Default behavior).
743
+ 2. Resume the sub-workflow from the failed task (set `resume_subworkflow_tasks` to True).
744
+
745
+ ### Restart Workflows
746
+
747
+ A workflow in the terminal state (COMPLETED, TERMINATED, FAILED) can be restarted from the beginning. Useful when retrying from the last failed task is insufficient, and the whole workflow must be started again.
748
+
749
+ ```python
750
+ restart_workflow(self, workflow_id: str, use_latest_def: Optional[bool] = False)
751
+ ```
752
+
753
+ ### Rerun Workflow from a Specific Task
754
+
755
+ In the cases where a workflow needs to be restarted from a specific task rather than from the beginning, rerun provides that option. When issuing the rerun command to the workflow, you can specify the task ID from where the workflow should be restarted (as opposed to from the beginning), and optionally, the workflow's input can also be changed.
756
+
757
+ ```python
758
+ rerun_workflow(self, workflow_id: str, rerun_workflow_request: RerunWorkflowRequest)
759
+ ```
760
+
761
+ > [!tip]
762
+ > Rerun is one of the most powerful features Conductor has, giving you unparalleled control over the workflow restart.
763
+ >
764
+
765
+ ### Pause Running Workflow
766
+
767
+ A running workflow can be put to a PAUSED status. A paused workflow lets the currently running tasks complete but does not schedule any new tasks until resumed.
768
+
769
+ ```python
770
+ pause_workflow(self, workflow_id: str)
771
+ ```
772
+
773
+ ### Resume Paused Workflow
774
+
775
+ Resume operation resumes the currently paused workflow, immediately evaluating its state and scheduling the next set of tasks.
776
+
777
+ ```python
778
+ resume_workflow(self, workflow_id: str)
779
+ ```
780
+
781
+ ### Searching for Workflows
782
+
783
+ Workflow executions are retained until removed from the Conductor. This gives complete visibility into all the executions an application has - regardless of the number of executions. Conductor has a powerful search API that allows you to search for workflow executions.
784
+
785
+ ```python
786
+ search(self, start, size, free_text: str = '*', query: str = None) -> ScrollableSearchResultWorkflowSummary
787
+ ```
788
+
789
+ * **free_text**: Free text search to look for specific words in the workflow and task input/output.
790
+ * **query** SQL-like query to search against specific fields in the workflow.
791
+
792
+ Here are the supported fields for **query**:
793
+
794
+ | Field | Description |
795
+ |-------------|-----------------|
796
+ | status |The status of the workflow. |
797
+ | correlationId |The ID to correlate the workflow execution to other executions. |
798
+ | workflowType |The name of the workflow. |
799
+ | version |The version of the workflow. |
800
+ |startTime|The start time of the workflow is in milliseconds.|
801
+
802
+
803
+ ### Handling Failures, Retries and Rate Limits
804
+
805
+ Conductor lets you embrace failures rather than worry about the complexities introduced in the system to handle failures.
806
+
807
+ All the aspects of handling failures, retries, rate limits, etc., are driven by the configuration that can be updated in real time without re-deploying your application.
808
+
809
+ #### Retries
810
+
811
+ Each task in the Conductor workflow can be configured to handle failures with retries, along with the retry policy (linear, fixed, exponential backoff) and maximum number of retry attempts allowed.
812
+
813
+ See [Error Handling](https://orkes.io/content/error-handling) for more details.
814
+
815
+ #### Rate Limits
816
+
817
+ What happens when a task is operating on a critical resource that can only handle a few requests at a time? Tasks can be configured to have a fixed concurrency (X request at a time) or a rate (Y tasks/time window).
818
+
819
+
820
+ #### Task Registration
821
+
822
+ ```python
823
+ from conductor.client.configuration.configuration import Configuration
824
+ from conductor.client.http.models import TaskDef
825
+ from conductor.client.orkes_clients import OrkesClients
826
+
827
+
828
+ def main():
829
+ api_config = Configuration()
830
+ clients = OrkesClients(configuration=api_config)
831
+ metadata_client = clients.get_metadata_client()
832
+
833
+ task_def = TaskDef()
834
+ task_def.name = 'task_with_retries'
835
+ task_def.retry_count = 3
836
+ task_def.retry_logic = 'LINEAR_BACKOFF'
837
+ task_def.retry_delay_seconds = 1
838
+
839
+ # only allow 3 tasks at a time to be in the IN_PROGRESS status
840
+ task_def.concurrent_exec_limit = 3
841
+
842
+ # timeout the task if not polled within 60 seconds of scheduling
843
+ task_def.poll_timeout_seconds = 60
844
+
845
+ # timeout the task if the task does not COMPLETE in 2 minutes
846
+ task_def.timeout_seconds = 120
847
+
848
+ # for the long running tasks, timeout if the task does not get updated in COMPLETED or IN_PROGRESS status in
849
+ # 60 seconds after the last update
850
+ task_def.response_timeout_seconds = 60
851
+
852
+ # only allow 100 executions in a 10-second window! -- Note, this is complementary to concurrent_exec_limit
853
+ task_def.rate_limit_per_frequency = 100
854
+ task_def.rate_limit_frequency_in_seconds = 10
855
+
856
+ metadata_client.register_task_def(task_def=task_def)
857
+ ```
858
+
859
+
860
+ ```json
861
+ {
862
+ "name": "task_with_retries",
863
+
864
+ "retryCount": 3,
865
+ "retryLogic": "LINEAR_BACKOFF",
866
+ "retryDelaySeconds": 1,
867
+ "backoffScaleFactor": 1,
868
+
869
+ "timeoutSeconds": 120,
870
+ "responseTimeoutSeconds": 60,
871
+ "pollTimeoutSeconds": 60,
872
+ "timeoutPolicy": "TIME_OUT_WF",
873
+
874
+ "concurrentExecLimit": 3,
875
+
876
+ "rateLimitPerFrequency": 0,
877
+ "rateLimitFrequencyInSeconds": 1
878
+ }
879
+ ```
880
+
881
+ #### Update Task Definition:
882
+
883
+ ```shell
884
+ POST /api/metadata/taskdef -d @task_def.json
885
+ ```
886
+
887
+ See [task_configure.py](examples/task_configure.py) for a detailed working app.
888
+
889
+ ## Using Conductor in Your Application
890
+
891
+ Conductor SDKs are lightweight and can easily be added to your existing or new Python app. This section will dive deeper into integrating Conductor in your application.
892
+
893
+ ### Adding Conductor SDK to Your Application
894
+
895
+ Conductor Python SDKs are published on PyPi @ https://pypi.org/project/conductor-python/:
896
+
897
+ ```shell
898
+ pip3 install conductor-python
899
+ ```
900
+
901
+ ### Testing Workflows
902
+
903
+ Conductor SDK for Python provides a complete feature testing framework for your workflow-based applications. The framework works well with any testing framework you prefer without imposing any specific framework.
904
+
905
+ The Conductor server provides a test endpoint `POST /api/workflow/test` that allows you to post a workflow along with the test execution data to evaluate the workflow.
906
+
907
+ The goal of the test framework is as follows:
908
+
909
+ 1. Ability to test the various branches of the workflow.
910
+ 2. Confirm the workflow execution and tasks given a fixed set of inputs and outputs.
911
+ 3. Validate that the workflow completes or fails given specific inputs.
912
+
913
+ Here are example assertions from the test:
914
+
915
+ ```python
916
+
917
+ ...
918
+ test_request = WorkflowTestRequest(name=wf.name, version=wf.version,
919
+ task_ref_to_mock_output=task_ref_to_mock_output,
920
+ workflow_def=wf.to_workflow_def())
921
+ run = workflow_client.test_workflow(test_request=test_request)
922
+
923
+ print(f'completed the test run')
924
+ print(f'status: {run.status}')
925
+ self.assertEqual(run.status, 'COMPLETED')
926
+
927
+ ...
928
+
929
+ ```
930
+
931
+ > [!note]
932
+ > Workflow workers are your regular Python functions and can be tested with any available testing framework.
933
+
934
+ #### Example Unit Testing Application
935
+
936
+ See [test_workflows.py](examples/test_workflows.py) for a fully functional example of how to test a moderately complex workflow with branches.
937
+
938
+ ### Workflow Deployments Using CI/CD
939
+
940
+ > [!tip]
941
+ > Treat your workflow definitions just like your code. Suppose you are defining the workflows using UI. In that case, we recommend checking the JSON configuration into the version control and using your development workflow for CI/CD to promote the workflow definitions across various environments such as Dev, Test, and Prod.
942
+
943
+ Here is a recommended approach when defining workflows using JSON:
944
+
945
+ * Treat your workflow metadata as code.
946
+ * Check in the workflow and task definitions along with the application code.
947
+ * Use `POST /api/metadata/*` endpoints or MetadataClient (`from conductor.client.metadata_client import MetadataClient`) to register/update workflows as part of the deployment process.
948
+ * Version your workflows. If there is a significant change, change the version field of the workflow. See versioning workflows below for more details.
949
+
950
+
951
+ ### Versioning Workflows
952
+
953
+ A powerful feature of Conductor is the ability to version workflows. You should increment the version of the workflow when there is a significant change to the definition. You can run multiple versions of the workflow at the same time. When starting a new workflow execution, use the `version` field to specify which version to use. When omitted, the latest (highest-numbered) version is used.
954
+
955
+ * Versioning allows safely testing changes by doing canary testing in production or A/B testing across multiple versions before rolling out.
956
+ * A version can also be deleted, effectively allowing for "rollback" if required.