dex-python-sdk 0.0.1__tar.gz → 0.1.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. dex_python_sdk-0.1.1/LEGACY_NOTICES.md +61 -0
  2. dex_python_sdk-0.1.1/LICENSE +192 -0
  3. dex_python_sdk-0.1.1/PKG-INFO +241 -0
  4. dex_python_sdk-0.1.1/README.md +224 -0
  5. dex_python_sdk-0.1.1/dex/__init__.py +157 -0
  6. dex_python_sdk-0.1.1/dex/_async_value_hydrator.py +223 -0
  7. dex_python_sdk-0.1.1/dex/_async_worker_dispatcher.py +139 -0
  8. dex_python_sdk-0.1.1/dex/_async_worker_service.py +65 -0
  9. dex_python_sdk-0.1.1/dex/_grpc_errors.py +86 -0
  10. dex_python_sdk-0.1.1/dex/_invocation_context.py +269 -0
  11. dex_python_sdk-0.1.1/dex/_native.pyi +20 -0
  12. dex_python_sdk-0.1.1/dex/_utils.py +18 -0
  13. dex_python_sdk-0.1.1/dex/_value_hydrator.py +223 -0
  14. dex_python_sdk-0.1.1/dex/_value_mapper.py +197 -0
  15. dex_python_sdk-0.1.1/dex/_worker_dispatcher.py +464 -0
  16. dex_python_sdk-0.1.1/dex/_worker_service.py +60 -0
  17. dex_python_sdk-0.1.1/dex/async_client.py +757 -0
  18. dex_python_sdk-0.1.1/dex/async_worker.py +106 -0
  19. dex_python_sdk-0.1.1/dex/attribute.py +87 -0
  20. dex_python_sdk-0.1.1/dex/blob_cache.py +73 -0
  21. dex_python_sdk-0.1.1/dex/channel.py +165 -0
  22. dex_python_sdk-0.1.1/dex/client.py +757 -0
  23. dex_python_sdk-0.1.1/dex/client_options.py +19 -0
  24. dex_python_sdk-0.1.1/dex/codec.py +286 -0
  25. dex_python_sdk-0.1.1/dex/condition.py +74 -0
  26. dex_python_sdk-0.1.1/dex/context.py +86 -0
  27. dex_python_sdk-0.1.1/dex/dexpb/dex_pb2.py +381 -0
  28. {dex_python_sdk-0.0.1 → dex_python_sdk-0.1.1}/dex/dexpb/dex_pb2.pyi +538 -77
  29. {dex_python_sdk-0.0.1 → dex_python_sdk-0.1.1}/dex/dexpb/dex_pb2_grpc.py +172 -0
  30. dex_python_sdk-0.1.1/dex/flow.py +488 -0
  31. dex_python_sdk-0.1.1/dex/flow_config.py +29 -0
  32. dex_python_sdk-0.1.1/dex/flow_info.py +57 -0
  33. dex_python_sdk-0.1.1/dex/flow_options.py +122 -0
  34. dex_python_sdk-0.1.1/dex/runtime_errors.py +81 -0
  35. dex_python_sdk-0.1.1/dex/step.py +194 -0
  36. dex_python_sdk-0.1.1/dex/step_execution.py +42 -0
  37. dex_python_sdk-0.1.1/dex/timer.py +21 -0
  38. dex_python_sdk-0.1.1/dex/wait.py +49 -0
  39. dex_python_sdk-0.1.1/dex/worker.py +121 -0
  40. dex_python_sdk-0.1.1/dex/worker_options.py +22 -0
  41. dex_python_sdk-0.1.1/pyproject.toml +81 -0
  42. dex_python_sdk-0.1.1/sdk-rust/Cargo.lock +1859 -0
  43. dex_python_sdk-0.1.1/sdk-rust/Cargo.toml +27 -0
  44. dex_python_sdk-0.1.1/sdk-rust/crates/dex-blob-cache/Cargo.toml +16 -0
  45. dex_python_sdk-0.1.1/sdk-rust/crates/dex-blob-cache/LICENSE +192 -0
  46. dex_python_sdk-0.1.1/sdk-rust/crates/dex-blob-cache/src/config.rs +86 -0
  47. dex_python_sdk-0.1.1/sdk-rust/crates/dex-blob-cache/src/entry.rs +113 -0
  48. dex_python_sdk-0.1.1/sdk-rust/crates/dex-blob-cache/src/error.rs +70 -0
  49. dex_python_sdk-0.1.1/sdk-rust/crates/dex-blob-cache/src/format.rs +100 -0
  50. dex_python_sdk-0.1.1/sdk-rust/crates/dex-blob-cache/src/lib.rs +428 -0
  51. dex_python_sdk-0.1.1/sdk-rust/crates/dex-blob-cache/src/policy.rs +219 -0
  52. dex_python_sdk-0.1.1/sdk-rust/crates/dex-blob-cache/src/store.rs +440 -0
  53. dex_python_sdk-0.1.1/sdk-rust/crates/dex-blob-cache/tests/blob_cache_integration.rs +321 -0
  54. dex_python_sdk-0.1.1/sdk-rust/crates/dex-blob-cache-python/Cargo.toml +16 -0
  55. dex_python_sdk-0.1.1/sdk-rust/crates/dex-blob-cache-python/LICENSE +192 -0
  56. dex_python_sdk-0.1.1/sdk-rust/crates/dex-blob-cache-python/src/lib.rs +61 -0
  57. dex_python_sdk-0.0.1/LICENSE +0 -201
  58. dex_python_sdk-0.0.1/PKG-INFO +0 -140
  59. dex_python_sdk-0.0.1/README.md +0 -117
  60. dex_python_sdk-0.0.1/dex/__init__.py +0 -14
  61. dex_python_sdk-0.0.1/dex/client.py +0 -568
  62. dex_python_sdk-0.0.1/dex/client_options.py +0 -34
  63. dex_python_sdk-0.0.1/dex/command_request.py +0 -130
  64. dex_python_sdk-0.0.1/dex/command_results.py +0 -116
  65. dex_python_sdk-0.0.1/dex/communication.py +0 -141
  66. dex_python_sdk-0.0.1/dex/communication_schema.py +0 -68
  67. dex_python_sdk-0.0.1/dex/data_attributes.py +0 -75
  68. dex_python_sdk-0.0.1/dex/dexpb/dex_pb2.py +0 -305
  69. dex_python_sdk-0.0.1/dex/errors.py +0 -132
  70. dex_python_sdk-0.0.1/dex/object_encoder.py +0 -818
  71. dex_python_sdk-0.0.1/dex/persistence.py +0 -94
  72. dex_python_sdk-0.0.1/dex/persistence_options.py +0 -24
  73. dex_python_sdk-0.0.1/dex/persistence_schema.py +0 -58
  74. dex_python_sdk-0.0.1/dex/registry.py +0 -209
  75. dex_python_sdk-0.0.1/dex/reset_workflow_type_and_options.py +0 -77
  76. dex_python_sdk-0.0.1/dex/rpc.py +0 -100
  77. dex_python_sdk-0.0.1/dex/search_attributes.py +0 -189
  78. dex_python_sdk-0.0.1/dex/state_decision.py +0 -161
  79. dex_python_sdk-0.0.1/dex/state_execution_locals.py +0 -71
  80. dex_python_sdk-0.0.1/dex/state_movement.py +0 -123
  81. dex_python_sdk-0.0.1/dex/state_schema.py +0 -54
  82. dex_python_sdk-0.0.1/dex/stop_workflow_options.py +0 -23
  83. dex_python_sdk-0.0.1/dex/tests/__init__.py +0 -84
  84. dex_python_sdk-0.0.1/dex/tests/dex-service-env/.env +0 -7
  85. dex_python_sdk-0.0.1/dex/tests/dex-service-env/docker-compose-init.sh +0 -44
  86. dex_python_sdk-0.0.1/dex/tests/dex-service-env/docker-compose.yml +0 -87
  87. dex_python_sdk-0.0.1/dex/tests/dex-service-env/dynamicconfig/README.md +0 -39
  88. dex_python_sdk-0.0.1/dex/tests/dex-service-env/dynamicconfig/development-sql.yaml +0 -6
  89. dex_python_sdk-0.0.1/dex/tests/dex-service-env/dynamicconfig/docker.yaml +0 -0
  90. dex_python_sdk-0.0.1/dex/tests/test_abnormal_exit_workflow.py +0 -48
  91. dex_python_sdk-0.0.1/dex/tests/test_basic_workflow.py +0 -75
  92. dex_python_sdk-0.0.1/dex/tests/test_conditional_complete.py +0 -56
  93. dex_python_sdk-0.0.1/dex/tests/test_describe_workflow.py +0 -45
  94. dex_python_sdk-0.0.1/dex/tests/test_empty_data_decodes_properly.py +0 -79
  95. dex_python_sdk-0.0.1/dex/tests/test_internal_channel.py +0 -33
  96. dex_python_sdk-0.0.1/dex/tests/test_internal_channel_with_no_prefix_channel.py +0 -46
  97. dex_python_sdk-0.0.1/dex/tests/test_persistence_data_attributes.py +0 -67
  98. dex_python_sdk-0.0.1/dex/tests/test_persistence_search_attributes.py +0 -132
  99. dex_python_sdk-0.0.1/dex/tests/test_persistence_state_execution_locals.py +0 -43
  100. dex_python_sdk-0.0.1/dex/tests/test_rpc.py +0 -69
  101. dex_python_sdk-0.0.1/dex/tests/test_rpc_with_memo.py +0 -200
  102. dex_python_sdk-0.0.1/dex/tests/test_rpc_with_memo_duplicate_java_tests.py +0 -122
  103. dex_python_sdk-0.0.1/dex/tests/test_signal.py +0 -56
  104. dex_python_sdk-0.0.1/dex/tests/test_skip_wait_until.py +0 -85
  105. dex_python_sdk-0.0.1/dex/tests/test_state_failure_recovery.py +0 -33
  106. dex_python_sdk-0.0.1/dex/tests/test_timer.py +0 -40
  107. dex_python_sdk-0.0.1/dex/tests/test_wait_for_state_execution_completion.py +0 -58
  108. dex_python_sdk-0.0.1/dex/tests/test_workflow_errors.py +0 -92
  109. dex_python_sdk-0.0.1/dex/tests/test_workflow_state_options.py +0 -123
  110. dex_python_sdk-0.0.1/dex/tests/test_workflow_state_options_override.py +0 -49
  111. dex_python_sdk-0.0.1/dex/tests/worker_server.py +0 -74
  112. dex_python_sdk-0.0.1/dex/tests/workflows/abnormal_exit_workflow.py +0 -48
  113. dex_python_sdk-0.0.1/dex/tests/workflows/basic_workflow.py +0 -69
  114. dex_python_sdk-0.0.1/dex/tests/workflows/conditional_complete_workflow.py +0 -101
  115. dex_python_sdk-0.0.1/dex/tests/workflows/describe_workflow.py +0 -52
  116. dex_python_sdk-0.0.1/dex/tests/workflows/empty_data_workflow.py +0 -51
  117. dex_python_sdk-0.0.1/dex/tests/workflows/internal_channel_workflow.py +0 -137
  118. dex_python_sdk-0.0.1/dex/tests/workflows/internal_channel_workflow_with_no_prefix_channel.py +0 -108
  119. dex_python_sdk-0.0.1/dex/tests/workflows/java_duplicate_rpc_memo_workflow.py +0 -285
  120. dex_python_sdk-0.0.1/dex/tests/workflows/persistence_data_attributes_workflow.py +0 -104
  121. dex_python_sdk-0.0.1/dex/tests/workflows/persistence_search_attributes_workflow.py +0 -167
  122. dex_python_sdk-0.0.1/dex/tests/workflows/persistence_state_execution_local_workflow.py +0 -69
  123. dex_python_sdk-0.0.1/dex/tests/workflows/recovery_workflow.py +0 -90
  124. dex_python_sdk-0.0.1/dex/tests/workflows/rpc_memo_workflow.py +0 -238
  125. dex_python_sdk-0.0.1/dex/tests/workflows/rpc_workflow.py +0 -125
  126. dex_python_sdk-0.0.1/dex/tests/workflows/state_options_override_workflow.py +0 -100
  127. dex_python_sdk-0.0.1/dex/tests/workflows/state_options_workflow.py +0 -92
  128. dex_python_sdk-0.0.1/dex/tests/workflows/timer_workflow.py +0 -52
  129. dex_python_sdk-0.0.1/dex/tests/workflows/wait_for_state_with_state_execution_id_workflow.py +0 -77
  130. dex_python_sdk-0.0.1/dex/tests/workflows/wait_for_state_with_wait_for_key_workflow.py +0 -78
  131. dex_python_sdk-0.0.1/dex/tests/workflows/wait_internal_channel_workflow.py +0 -53
  132. dex_python_sdk-0.0.1/dex/tests/workflows/wait_signal_workflow.py +0 -154
  133. dex_python_sdk-0.0.1/dex/type_store.py +0 -105
  134. dex_python_sdk-0.0.1/dex/unregistered_client.py +0 -595
  135. dex_python_sdk-0.0.1/dex/utils/__init__.py +0 -14
  136. dex_python_sdk-0.0.1/dex/utils/dex_typing.py +0 -31
  137. dex_python_sdk-0.0.1/dex/utils/persistence_utils.py +0 -37
  138. dex_python_sdk-0.0.1/dex/worker_service.py +0 -441
  139. dex_python_sdk-0.0.1/dex/workflow.py +0 -86
  140. dex_python_sdk-0.0.1/dex/workflow_context.py +0 -50
  141. dex_python_sdk-0.0.1/dex/workflow_info.py +0 -21
  142. dex_python_sdk-0.0.1/dex/workflow_options.py +0 -79
  143. dex_python_sdk-0.0.1/dex/workflow_state.py +0 -134
  144. dex_python_sdk-0.0.1/dex/workflow_state_options.py +0 -160
  145. dex_python_sdk-0.0.1/pyproject.toml +0 -54
  146. {dex_python_sdk-0.0.1 → dex_python_sdk-0.1.1}/dex/dexpb/__init__.py +0 -0
  147. {dex_python_sdk-0.0.1 → dex_python_sdk-0.1.1}/dex/py.typed +0 -0
@@ -0,0 +1,61 @@
1
+ # Legacy and third-party notices
2
+
3
+ The Super Durable Source License 1.0 applies only to material owned or
4
+ licensable by Super Durable, Inc. It does not replace the licenses below.
5
+
6
+ ## Legacy cutoff
7
+
8
+ The complete repository snapshot at commit
9
+ `1a61670238cbdc8f2a0a6dd78cc5668fb014f283`, including both parents of that
10
+ merge commit, is Legacy Materials. Later copies and adaptations retain the
11
+ applicable legacy license for their legacy portions.
12
+
13
+ At the cutoff, the principal directory licenses were:
14
+
15
+ | Cutoff path | Legacy license |
16
+ | --- | --- |
17
+ | `server/` | MIT |
18
+ | `sdk-go/` | Apache License 2.0 |
19
+ | `sdk-java/` | Apache License 2.0 |
20
+ | `sdk-python/` | Apache License 2.0 |
21
+ | `protos/` | MIT or Apache License 2.0, at the recipient's option |
22
+ | `samples-go/` | MIT |
23
+ | `samples-java/` | Apache License 2.0 |
24
+ | `samples-python/` | Apache License 2.0 |
25
+
26
+ The MIT and Apache License 2.0 texts are in `LICENSES/`. Historical copyright
27
+ and attribution notices remain authoritative and must be preserved. Git history
28
+ identifies the exact material present at the cutoff.
29
+
30
+ ## Excluded directories
31
+
32
+ This relicensing does not cover `docs/` or `examples/`.
33
+
34
+ - `examples/go/` remains under its existing MIT License.
35
+ - `examples/java/` and `examples/python/` remain under their existing Apache
36
+ License 2.0 terms.
37
+ - `docs/` retains its legacy copyright and licensing status. This repository
38
+ makes no new license grant for that directory.
39
+
40
+ ## Existing third-party notices
41
+
42
+ Some source files retain notices naming Cadence workflow OSS organization,
43
+ Uber Technologies, Inc., Indeed, Inc., individual contributors, or other
44
+ holders. Those notices and their accompanying licenses remain in force.
45
+
46
+ Dependencies not copied into this repository remain governed by the license
47
+ distributed with each dependency.
48
+
49
+ ## IWF Java SDK integration fixtures
50
+
51
+ The workflow and integration-test fixtures under these paths are adaptations
52
+ or translations of the `indeedeng/iwf-java-sdk` integration suite at commit
53
+ `8fa04457c0abcc4473300f17ea0a033d8f93ed88`:
54
+
55
+ - `sdk-java/src/test/java/io/superdurable/dex/integ/`
56
+ - `sdk-python/tests/integ/`
57
+ - `sdk-typescript/test/integ/`
58
+
59
+ The upstream portions remain licensed under the Apache License 2.0. Super
60
+ Durable modifications are licensed under the Super Durable Source License 1.0.
61
+ The Apache License 2.0 text is in `LICENSES/Apache-2.0.txt`.
@@ -0,0 +1,192 @@
1
+ Super Durable Source License 1.0
2
+
3
+ Copyright (c) 2026 Super Durable, Inc.
4
+
5
+ Acceptance
6
+
7
+ This agreement governs the Software made available by Super Durable, Inc.
8
+ ("Licensor"). By copying, modifying, distributing, or using the Software, You
9
+ accept this agreement. If You act for an entity, You represent that You have
10
+ authority to bind that entity, and "You" means that entity.
11
+
12
+ License Grant
13
+
14
+ Subject to this agreement, Licensor grants You a non-exclusive, worldwide,
15
+ non-transferable, non-sublicensable license to copy and modify the Software and
16
+ to use it for Non-Production Use.
17
+
18
+ Licensor also grants You a license to make Production Use when either:
19
+
20
+ 1. You are a Qualified User; or
21
+ 2. You have a current Subscription authorizing that Production Use.
22
+
23
+ If You cease to be a Qualified User, You may continue the same Production Use
24
+ for ninety (90) days after the end of the first fiscal year for which Your
25
+ Consolidated Annual Revenue exceeds the Revenue Threshold. After that grace
26
+ period, continued Production Use requires a Subscription.
27
+
28
+ The licenses in this section include the right to make, have made, use, sell,
29
+ offer for sale, and import the Software only under patent claims Licensor can
30
+ license that are necessarily infringed by the Software as provided by
31
+ Licensor. If You bring a written patent infringement claim concerning the
32
+ Software, this patent license terminates immediately.
33
+
34
+ Applications and Client Components
35
+
36
+ While otherwise complying with this agreement, You may distribute Client
37
+ Components, in source or object form, solely as an embedded or bundled part of
38
+ an Application. The Application must have a primary purpose other than
39
+ providing the Software, a Competitive Product, or a hosted Dex-compatible
40
+ service.
41
+
42
+ A recipient may run an Application containing Client Components without a
43
+ separate Subscription. This exception does not permit the recipient to extract,
44
+ modify, redistribute, or use Client Components independently, or to deploy or
45
+ operate other Software. A person that develops or operates an Application is
46
+ still subject to the Production Use and Revenue Threshold requirements.
47
+
48
+ Competitive Use
49
+
50
+ You may not make Competitive Use without a separate written commercial license
51
+ from Licensor. The Revenue Threshold, Qualified User status, grace period, and
52
+ Application exception do not authorize Competitive Use.
53
+
54
+ Source Collaboration
55
+
56
+ You may publicly host a source fork or distribute patches solely for
57
+ evaluation, internal development, or contribution to Licensor, provided You:
58
+
59
+ 1. do not make Production Use or Competitive Use through that distribution;
60
+ 2. preserve this agreement and all copyright, attribution, and license notices;
61
+ 3. identify files You modified; and
62
+ 4. apply this agreement to Your modifications to the Software.
63
+
64
+ No other redistribution of the Software or a Modified Version is permitted
65
+ except under the Application exception or a Subscription.
66
+
67
+ Legacy and Third-Party Materials
68
+
69
+ This agreement applies only to the Software and modifications owned or
70
+ licensable by Licensor. It does not replace or restrict any license applying to
71
+ Legacy Materials or Third-Party Materials. Those materials remain governed by
72
+ their respective licenses. Their notices and license texts must be preserved.
73
+ See LEGACY_NOTICES.md and accompanying third-party notices.
74
+
75
+ Commercial Licenses
76
+
77
+ A Subscription or other written commercial agreement may grant additional
78
+ rights. If its terms conflict with this agreement, the commercial agreement
79
+ controls only for the Software, use, and period it expressly covers. Contact
80
+ licensing@superdurable.io for a Subscription or Competitive Use license.
81
+
82
+ Restrictions and Obligations
83
+
84
+ You must not:
85
+
86
+ 1. remove or obscure copyright, license, attribution, or trademark notices;
87
+ 2. represent that Licensor endorses You or Your products;
88
+ 3. use Licensor's names, marks, or logos except to accurately identify the
89
+ origin of the Software; or
90
+ 4. enable another person to exercise rights that this agreement does not grant.
91
+
92
+ You are responsible for Your affiliates, contractors, and agents that use the
93
+ Software on Your behalf. You must comply with applicable export, import, and
94
+ sanctions laws.
95
+
96
+ Termination
97
+
98
+ Your rights terminate automatically if You breach this agreement. If the breach
99
+ is capable of cure and is neither intentional nor repeated, Your rights are
100
+ reinstated retroactively when You cure it within fifteen (15) days after the
101
+ breach. Intentional or repeated breaches permanently terminate Your rights
102
+ unless Licensor agrees otherwise in writing.
103
+
104
+ No Other Rights
105
+
106
+ Except for rights expressly granted here, Licensor reserves all rights. This
107
+ agreement grants no trademark rights and does not require Licensor to provide
108
+ support, maintenance, updates, or a Subscription.
109
+
110
+ Disclaimer
111
+
112
+ TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" AND
113
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
114
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE, NON-INFRINGEMENT,
115
+ ACCURACY, OR UNINTERRUPTED OR ERROR-FREE OPERATION.
116
+
117
+ Limitation of Liability
118
+
119
+ TO THE MAXIMUM EXTENT PERMITTED BY LAW, LICENSOR WILL NOT BE LIABLE FOR ANY
120
+ INDIRECT, SPECIAL, INCIDENTAL, CONSEQUENTIAL, EXEMPLARY, OR PUNITIVE DAMAGES,
121
+ OR FOR LOST PROFITS, REVENUE, DATA, OR BUSINESS INTERRUPTION. LICENSOR'S TOTAL
122
+ LIABILITY ARISING FROM THIS AGREEMENT OR THE SOFTWARE WILL NOT EXCEED ONE
123
+ HUNDRED U.S. DOLLARS (US$100), REGARDLESS OF THE LEGAL THEORY AND EVEN IF
124
+ LICENSOR WAS ADVISED THAT SUCH DAMAGES WERE POSSIBLE.
125
+
126
+ Governing Law
127
+
128
+ Delaware law and applicable United States federal law govern this agreement,
129
+ without regard to conflict-of-law rules. The state and federal courts located
130
+ in Delaware have exclusive jurisdiction. The United Nations Convention on
131
+ Contracts for the International Sale of Goods does not apply.
132
+
133
+ Definitions
134
+
135
+ "Affiliate" means an entity that directly or indirectly controls, is controlled
136
+ by, or is under common control with You. "Control" means ownership of more than
137
+ fifty percent (50%) of voting interests or the power to direct management.
138
+
139
+ "Application" means software developed for a business or end-user purpose whose
140
+ primary purpose is not to provide the Software or a Competitive Product.
141
+
142
+ "Client Components" means the SDK and protocol-definition portions of the
143
+ Software intended to be integrated into Applications.
144
+
145
+ "Competitive Product" means software or a service whose primary purpose is to
146
+ replace or provide substantially similar functionality to a Dex server, Dex
147
+ SDK, Dex command-line product, Dex web product, or a hosted Dex-compatible
148
+ service. An Application, connector, plug-in, or adapter that merely interoperates
149
+ with Dex is not a Competitive Product.
150
+
151
+ "Competitive Use" means developing, distributing, offering, or operating a
152
+ Competitive Product for any third party.
153
+
154
+ "Consolidated Annual Revenue" means the gross revenue of You and all Affiliates,
155
+ without double counting intercompany transactions, for the most recently
156
+ completed fiscal year, as determined under consistently applied GAAP or IFRS.
157
+ Non-U.S.-dollar revenue is converted to U.S. dollars using the exchange rate
158
+ used in the applicable consolidated financial statements. If You have no
159
+ completed fiscal year, use a good-faith annualization of revenue since formation.
160
+
161
+ "Legacy Cutoff" means Git commit
162
+ 1a61670238cbdc8f2a0a6dd78cc5668fb014f283 in the Software's repository.
163
+
164
+ "Legacy Materials" means material contained in the complete repository snapshot
165
+ at the Legacy Cutoff, including material reachable through either parent of that
166
+ merge commit, and later copies or adaptations of that material, to the extent
167
+ governed by a license other than this agreement.
168
+
169
+ "Modified Version" means any modification or derivative work of the Software.
170
+
171
+ "Non-Production Use" means design, prototyping, evaluation, testing, or
172
+ development that does not serve live end users, process live business workloads,
173
+ or support production operations.
174
+
175
+ "Production Use" means any use other than Non-Production Use.
176
+
177
+ "Qualified User" means You when Your Consolidated Annual Revenue does not exceed
178
+ the Revenue Threshold and You are not making Competitive Use.
179
+
180
+ "Revenue Threshold" means ten million U.S. dollars (US$10,000,000).
181
+
182
+ "Software" means files in this repository that include or refer to this
183
+ agreement, in source or object form, excluding the docs/ and examples/
184
+ directories, Legacy Materials, and Third-Party Materials.
185
+
186
+ "Subscription" means a current written commercial subscription or license from
187
+ Licensor that authorizes the applicable Production Use.
188
+
189
+ "Third-Party Materials" means material owned by a third party and provided under
190
+ separate license terms.
191
+
192
+ "You" means the individual or legal entity accepting this agreement.
@@ -0,0 +1,241 @@
1
+ Metadata-Version: 2.4
2
+ Name: dex-python-sdk
3
+ Version: 0.1.1
4
+ Requires-Dist: grpcio>=1.83.0
5
+ Requires-Dist: grpcio-status>=1.83.0
6
+ Requires-Dist: protobuf>=7.35.1
7
+ License-File: LICENSE
8
+ License-File: LEGACY_NOTICES.md
9
+ Summary: Python SDK for the Dex workflow engine
10
+ Author: Super Durable
11
+ License-Expression: LicenseRef-Super-Durable-1.0
12
+ Requires-Python: >=3.11
13
+ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
14
+ Project-URL: Homepage, https://github.com/superdurable/dex/tree/main/sdk-python
15
+ Project-URL: Repository, https://github.com/superdurable/dex
16
+
17
+
18
+ # Dex SDK for Python
19
+
20
+ Python SDK for [Dex workflow engine](https://github.com/superdurable/dex)
21
+
22
+ ## New user contracts
23
+
24
+ The rewrite targets Python 3.11+ and exposes strongly typed workflow contracts
25
+ from `dex`. This phase includes definitions, attributes, channels, waits,
26
+ decisions, codecs, registry validation, synchronous client calls, and synchronous
27
+ worker handlers. Python owns its gRPC Client and Worker transport;
28
+ the shared Rust Core is used only for BlobCache.
29
+
30
+ ```python
31
+ from datetime import timedelta
32
+
33
+ import dex
34
+
35
+ counter = dex.Attribute("counter", int)
36
+ counters_by_region = dex.AttributeMap("counters-by-region", int)
37
+
38
+ class Run(dex.Step[str]):
39
+ def wait_for(
40
+ self, context: dex.Context, input: str
41
+ ) -> dex.Wait:
42
+ return dex.Wait.all_of(
43
+ dex.Timer.by_duration(timedelta(seconds=1))
44
+ )
45
+
46
+ def execute(
47
+ self, context: dex.Context, input: str
48
+ ) -> dex.StepDecision:
49
+ return dex.graceful_complete(input)
50
+
51
+ class CounterFlow(dex.Flow[str]):
52
+ run = Run()
53
+
54
+ def get_flow_type(self) -> str:
55
+ return "Counter"
56
+
57
+ def get_steps(self) -> dex.StepList[str]:
58
+ return dex.StepList.start_step(self.run)
59
+
60
+ def get_persistence_schema(self) -> dex.PersistenceSchema:
61
+ return dex.PersistenceSchema.of(counter, counters_by_region)
62
+
63
+ @dex.rpc(name="Increment")
64
+ def increment(
65
+ self, context: dex.Context, input: int
66
+ ) -> dex.RPCResult[int]:
67
+ return dex.RPCResult(input + 1)
68
+
69
+ flow = CounterFlow()
70
+ registry = dex.Registry((flow,))
71
+ ```
72
+
73
+ Registry derives codecs from declared Python types and handler annotations.
74
+ Built-in scalar types and dataclasses need no codec arguments. Register an
75
+ explicit codec only for a custom encoding or a type Registry cannot derive.
76
+ `PersistenceSchema.of(...)` accepts attributes and channels together and
77
+ partitions them by definition type.
78
+
79
+ Initial attributes retain their value types without a public wrapper class:
80
+
81
+ ```python
82
+ options = (
83
+ dex.StartFlowOptions()
84
+ .with_attribute(counter, 1)
85
+ .with_attribute(counters_by_region, "us-west", 1)
86
+ )
87
+ ```
88
+
89
+ ```
90
+ pip install dex-python-sdk==0.1.0
91
+ ```
92
+
93
+ See [samples](../examples/python) for use case examples.
94
+
95
+ ## Requirements
96
+
97
+ - Python 3.11+
98
+ - [Dex server](https://github.com/superdurable/dex#how-to-use)
99
+
100
+ ## Concepts
101
+
102
+ Applications implement two generic interfaces from [`dex`](dex/):
103
+
104
+ - `Flow[START_INPUT]` returns `StepList.start_step(...)`, followed by optional
105
+ `.other_steps(...)`, from one `get_steps()` method. The `StepList` generic
106
+ binds the Flow input to the starting Step input. Use `StepList.empty()` when
107
+ a Flow has no Steps.
108
+ - `Step[INPUT]` implements `execute` and optionally `wait_for`. The default
109
+ Worker path requires synchronous handlers. With `AsyncWorker` and
110
+ `Registry(..., allow_async_handlers=True)`, handlers may be `async def` and
111
+ `await` an `AsyncClient`.
112
+
113
+ `StepOptions.wait_for_method_timeout` and `execute_method_timeout` bound the
114
+ two handler calls. Timer and channel conditions determine how long a Step waits.
115
+
116
+ `Registry` validates every Flow, Step, RPC signature, durable name, lock, and
117
+ codec before Client or Worker startup. `Client` methods use these typed objects
118
+ instead of raw Flow, Step, or RPC strings.
119
+
120
+ ### Sync vs asyncio
121
+
122
+ - **Sync (default):** `Client` and `Worker` use blocking gRPC and a thread-pool
123
+ Worker. Blocking `Client` calls inside `Step.execute` are safe (one pool
124
+ thread is occupied; other RPCs still run).
125
+ - **Asyncio:** `AsyncClient` and `AsyncWorker` use `grpc.aio`. Use
126
+ `Registry(..., allow_async_handlers=True)` when Steps/RPCs are coroutines.
127
+ Inside async `execute`, inject `AsyncClient` — do not call sync `Client` on
128
+ the Worker event loop. Sync `Worker` still rejects coroutine handlers at
129
+ registry construction unless `allow_async_handlers=True` (and even then the
130
+ sync Worker dispatcher rejects awaitable return values).
131
+
132
+ Integration scenarios live under
133
+ [`tests/integ`](tests/integ/README.md). They exercise the same workflows,
134
+ client operations, and assertions as the Java suite against an isolated
135
+ `dexcli dev` environment.
136
+
137
+ ## Implementation status
138
+
139
+ The strongly typed contracts, registry, synchronous Client/Worker, optional
140
+ `AsyncClient`/`AsyncWorker` (`grpc.aio`), and Rust-backed BlobCache are
141
+ implemented. Python owns its gRPC transport; the native bridge is limited to
142
+ the shared BlobCache. Design notes:
143
+ [`docs/design/plan/python-sdk-async-apis.md`](../docs/design/plan/python-sdk-async-apis.md).
144
+
145
+ ## Running dex-server locally
146
+
147
+ ### Option 1: use docker compose
148
+ See [dex README](https://github.com/superdurable/dex#using-docker-image--docker-compose)
149
+
150
+ ### Option 2: VSCode Dev Container
151
+
152
+ Dev Container is an easy way to get dex-server running locally. Follow these steps to launch a dev container:
153
+ - Install Docker, VSCode, and [VSCode Dev Container plugin](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers).
154
+ - Open the project in VSCode.
155
+ ```bash
156
+ cd dex-python-sdk
157
+ code .
158
+ ```
159
+ - Launch the Remote-Containers: Reopen in Container command from Command Palette (Ctrl + Shift + P). You can also click in the bottom left corner to access the remote container menu.
160
+ - Once the dev container starts, dex-server will be listening on port 8801.
161
+
162
+ ## How To Contribute
163
+
164
+ This project uses [uv](https://docs.astral.sh/uv/) for Python versions,
165
+ dependencies, virtual environments, locking, building, and publishing.
166
+
167
+ To install requirements:
168
+
169
+ ```bash
170
+ uv sync --locked
171
+ ```
172
+
173
+ Run the complete Python SDK integration suite with an isolated Dex development
174
+ environment:
175
+
176
+ ```bash
177
+ ./run-integration-tests.sh
178
+ ```
179
+
180
+ ### Measure integration coverage
181
+
182
+ Run the same integration suite with Python source coverage:
183
+
184
+ ```bash
185
+ ./run-integration-tests.sh --coverage
186
+ ```
187
+
188
+ Only the integration scenarios contribute execution data, and only production
189
+ Python modules under `dex` are measured. Generated protobuf modules under
190
+ `dex/dexpb` are excluded. The
191
+ terminal report lists uncovered line ranges. The browser report starts at
192
+ `coverage/html/index.html`; `coverage/coverage.xml` and `coverage/lcov.info`
193
+ are also generated.
194
+
195
+ CI uploads LCOV to Codecov with GitHub OIDC under the
196
+ `sdk-python-integration` flag and retains the full report as the
197
+ `sdk-python-integration-coverage` Actions artifact.
198
+
199
+ #### Update IDL
200
+
201
+ Edit [`protos/dex.proto`](../protos/dex.proto). Rename catalog: [`docs/design/idl-renames.md`](../docs/design/idl-renames.md).
202
+
203
+ #### Generate stubs from IDL
204
+
205
+ ```bash
206
+ make -C ../protos proto-python
207
+ ```
208
+
209
+ Checked-in Python stubs land in `dex/dexpb/`.
210
+ #### Linting
211
+
212
+ To run linting for this project:
213
+
214
+ ```bash
215
+ uv run --frozen pre-commit run --show-diff-on-failure --color=always --all-files
216
+ ```
217
+
218
+ ## Code of Conduct
219
+ This project is governed by the [Contributor Covenant v 1.4.1](CODE_OF_CONDUCT.md). (Review the Code of Conduct and remove this sentence before publishing your project.)
220
+
221
+ ## Publishing to PyPI
222
+
223
+ 1. Optionally run **Publish Python SDK to PyPI** via workflow_dispatch with a version and
224
+ `publish=false` to validate all distributions without uploading.
225
+ 2. Create a GitHub Release with tag `sdk-python/vX.Y.Z` (for example `sdk-python/v0.1.0`).
226
+ CI stamps that version into `pyproject.toml` for the build (same idea as the TypeScript
227
+ SDK release), then builds and smoke-tests Linux x86_64/ARM64, macOS x86_64/ARM64, and
228
+ Windows x86_64 wheels, verifies the source distribution, and publishes with `PYPI_TOKEN`.
229
+ 3. After publishing, bump the committed `pyproject.toml` / docs install line when you want
230
+ the repo tip to reflect the released version.
231
+
232
+ A manual run publishes only from `main`, and only when `publish` is explicitly selected.
233
+ The dispatch `version` input is stamped the same way as a release tag.
234
+
235
+ See [CONTRIBUTING.md](../CONTRIBUTING.md#releases-monorepo-tags) for monorepo tag conventions.
236
+
237
+ ## License
238
+
239
+ [Super Durable Source License 1.0](LICENSE), with legacy portions under their
240
+ original terms as described in [LEGACY_NOTICES.md](LEGACY_NOTICES.md).
241
+