dex-python-sdk 0.0.1__tar.gz → 0.0.2__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.
- dex_python_sdk-0.0.2/LEGACY_NOTICES.md +61 -0
- dex_python_sdk-0.0.2/LICENSE +192 -0
- dex_python_sdk-0.0.2/PKG-INFO +202 -0
- dex_python_sdk-0.0.2/README.md +184 -0
- dex_python_sdk-0.0.2/dex/__init__.py +146 -0
- dex_python_sdk-0.0.2/dex/_grpc_errors.py +73 -0
- dex_python_sdk-0.0.2/dex/_invocation_context.py +269 -0
- dex_python_sdk-0.0.2/dex/_native.pyi +20 -0
- dex_python_sdk-0.0.2/dex/_utils.py +18 -0
- dex_python_sdk-0.0.2/dex/_value_hydrator.py +223 -0
- dex_python_sdk-0.0.2/dex/_value_mapper.py +174 -0
- dex_python_sdk-0.0.2/dex/_worker_dispatcher.py +451 -0
- dex_python_sdk-0.0.2/dex/_worker_service.py +60 -0
- dex_python_sdk-0.0.2/dex/attribute.py +87 -0
- dex_python_sdk-0.0.2/dex/blob_cache.py +73 -0
- dex_python_sdk-0.0.2/dex/channel.py +165 -0
- dex_python_sdk-0.0.2/dex/client.py +715 -0
- dex_python_sdk-0.0.2/dex/client_options.py +19 -0
- dex_python_sdk-0.0.2/dex/codec.py +286 -0
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/command_request.py +8 -18
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/command_results.py +8 -17
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/communication.py +8 -13
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/communication_schema.py +2 -16
- dex_python_sdk-0.0.2/dex/condition.py +74 -0
- dex_python_sdk-0.0.2/dex/context.py +86 -0
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/data_attributes.py +8 -13
- dex_python_sdk-0.0.2/dex/dexpb/dex_pb2.py +381 -0
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/dexpb/dex_pb2.pyi +538 -77
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/dexpb/dex_pb2_grpc.py +172 -0
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/errors.py +8 -31
- dex_python_sdk-0.0.2/dex/flow.py +456 -0
- dex_python_sdk-0.0.2/dex/flow_config.py +29 -0
- dex_python_sdk-0.0.2/dex/flow_info.py +51 -0
- dex_python_sdk-0.0.2/dex/flow_options.py +122 -0
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/object_encoder.py +8 -27
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/persistence.py +8 -13
- dex_python_sdk-0.0.2/dex/persistence_options.py +12 -0
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/persistence_schema.py +8 -15
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/registry.py +8 -13
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/reset_workflow_type_and_options.py +8 -18
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/rpc.py +8 -15
- dex_python_sdk-0.0.2/dex/runtime_errors.py +81 -0
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/search_attributes.py +8 -13
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/state_decision.py +8 -16
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/state_execution_locals.py +8 -13
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/state_movement.py +8 -16
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/state_schema.py +8 -14
- dex_python_sdk-0.0.2/dex/step.py +194 -0
- dex_python_sdk-0.0.2/dex/step_execution.py +42 -0
- dex_python_sdk-0.0.2/dex/stop_workflow_options.py +18 -0
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/tests/__init__.py +8 -12
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/tests/dex-service-env/docker-compose-init.sh +0 -0
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/tests/dex-service-env/docker-compose.yml +10 -0
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/tests/dex-service-env/dynamicconfig/development-sql.yaml +3 -0
- dex_python_sdk-0.0.2/dex/tests/dex-service-env/dynamicconfig/docker.yaml +2 -0
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/tests/test_abnormal_exit_workflow.py +8 -13
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/tests/test_basic_workflow.py +8 -13
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/tests/test_conditional_complete.py +8 -14
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/tests/test_describe_workflow.py +8 -13
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/tests/test_empty_data_decodes_properly.py +8 -13
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/tests/test_internal_channel.py +8 -13
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/tests/test_internal_channel_with_no_prefix_channel.py +8 -13
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/tests/test_persistence_data_attributes.py +8 -13
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/tests/test_persistence_search_attributes.py +8 -13
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/tests/test_persistence_state_execution_locals.py +8 -13
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/tests/test_rpc.py +8 -13
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/tests/test_rpc_with_memo.py +8 -13
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/tests/test_rpc_with_memo_duplicate_java_tests.py +8 -13
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/tests/test_signal.py +8 -13
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/tests/test_skip_wait_until.py +8 -17
- dex_python_sdk-0.0.2/dex/tests/test_state_failure_recovery.py +28 -0
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/tests/test_timer.py +8 -13
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/tests/test_wait_for_state_execution_completion.py +8 -13
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/tests/test_workflow_errors.py +8 -13
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/tests/test_workflow_state_options.py +8 -13
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/tests/test_workflow_state_options_override.py +8 -13
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/tests/worker_server.py +8 -18
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/tests/workflows/abnormal_exit_workflow.py +8 -14
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/tests/workflows/basic_workflow.py +8 -15
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/tests/workflows/conditional_complete_workflow.py +8 -14
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/tests/workflows/describe_workflow.py +8 -14
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/tests/workflows/empty_data_workflow.py +8 -14
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/tests/workflows/internal_channel_workflow.py +8 -16
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/tests/workflows/internal_channel_workflow_with_no_prefix_channel.py +8 -16
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/tests/workflows/java_duplicate_rpc_memo_workflow.py +8 -17
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/tests/workflows/persistence_data_attributes_workflow.py +8 -14
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/tests/workflows/persistence_search_attributes_workflow.py +8 -16
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/tests/workflows/persistence_state_execution_local_workflow.py +8 -14
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/tests/workflows/recovery_workflow.py +8 -16
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/tests/workflows/rpc_memo_workflow.py +8 -15
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/tests/workflows/rpc_workflow.py +8 -16
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/tests/workflows/state_options_override_workflow.py +8 -15
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/tests/workflows/state_options_workflow.py +8 -16
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/tests/workflows/timer_workflow.py +8 -14
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/tests/workflows/wait_for_state_with_state_execution_id_workflow.py +8 -15
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/tests/workflows/wait_for_state_with_wait_for_key_workflow.py +8 -15
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/tests/workflows/wait_internal_channel_workflow.py +8 -14
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/tests/workflows/wait_signal_workflow.py +8 -15
- dex_python_sdk-0.0.2/dex/timer.py +21 -0
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/type_store.py +8 -14
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/unregistered_client.py +8 -18
- dex_python_sdk-0.0.2/dex/utils/__init__.py +3 -0
- dex_python_sdk-0.0.2/dex/utils/dex_typing.py +25 -0
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/utils/persistence_utils.py +8 -13
- dex_python_sdk-0.0.2/dex/wait.py +49 -0
- dex_python_sdk-0.0.2/dex/worker.py +121 -0
- dex_python_sdk-0.0.2/dex/worker_options.py +22 -0
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/worker_service.py +10 -19
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/workflow.py +8 -15
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/workflow_context.py +8 -14
- dex_python_sdk-0.0.2/dex/workflow_info.py +16 -0
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/workflow_options.py +8 -13
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/workflow_state.py +8 -19
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/workflow_state_options.py +8 -14
- dex_python_sdk-0.0.2/pyproject.toml +72 -0
- dex_python_sdk-0.0.2/sdk-rust/Cargo.lock +1700 -0
- dex_python_sdk-0.0.2/sdk-rust/Cargo.toml +24 -0
- dex_python_sdk-0.0.2/sdk-rust/crates/dex-blob-cache/Cargo.toml +16 -0
- dex_python_sdk-0.0.2/sdk-rust/crates/dex-blob-cache/LICENSE +192 -0
- dex_python_sdk-0.0.2/sdk-rust/crates/dex-blob-cache/src/config.rs +86 -0
- dex_python_sdk-0.0.2/sdk-rust/crates/dex-blob-cache/src/entry.rs +113 -0
- dex_python_sdk-0.0.2/sdk-rust/crates/dex-blob-cache/src/error.rs +70 -0
- dex_python_sdk-0.0.2/sdk-rust/crates/dex-blob-cache/src/format.rs +100 -0
- dex_python_sdk-0.0.2/sdk-rust/crates/dex-blob-cache/src/lib.rs +428 -0
- dex_python_sdk-0.0.2/sdk-rust/crates/dex-blob-cache/src/policy.rs +219 -0
- dex_python_sdk-0.0.2/sdk-rust/crates/dex-blob-cache/src/store.rs +440 -0
- dex_python_sdk-0.0.2/sdk-rust/crates/dex-blob-cache/tests/blob_cache_integration.rs +321 -0
- dex_python_sdk-0.0.2/sdk-rust/crates/dex-blob-cache-python/Cargo.toml +16 -0
- dex_python_sdk-0.0.2/sdk-rust/crates/dex-blob-cache-python/LICENSE +192 -0
- dex_python_sdk-0.0.2/sdk-rust/crates/dex-blob-cache-python/src/lib.rs +61 -0
- dex_python_sdk-0.0.1/LICENSE +0 -201
- dex_python_sdk-0.0.1/PKG-INFO +0 -140
- dex_python_sdk-0.0.1/README.md +0 -117
- dex_python_sdk-0.0.1/dex/__init__.py +0 -14
- dex_python_sdk-0.0.1/dex/client.py +0 -568
- dex_python_sdk-0.0.1/dex/client_options.py +0 -34
- dex_python_sdk-0.0.1/dex/dexpb/dex_pb2.py +0 -305
- dex_python_sdk-0.0.1/dex/persistence_options.py +0 -24
- dex_python_sdk-0.0.1/dex/stop_workflow_options.py +0 -23
- dex_python_sdk-0.0.1/dex/tests/dex-service-env/.env +0 -7
- dex_python_sdk-0.0.1/dex/tests/dex-service-env/dynamicconfig/docker.yaml +0 -0
- dex_python_sdk-0.0.1/dex/tests/test_state_failure_recovery.py +0 -33
- dex_python_sdk-0.0.1/dex/utils/__init__.py +0 -14
- dex_python_sdk-0.0.1/dex/utils/dex_typing.py +0 -31
- dex_python_sdk-0.0.1/dex/workflow_info.py +0 -21
- dex_python_sdk-0.0.1/pyproject.toml +0 -54
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/dexpb/__init__.py +0 -0
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/py.typed +0 -0
- {dex_python_sdk-0.0.1 → dex_python_sdk-0.0.2}/dex/tests/dex-service-env/dynamicconfig/README.md +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,202 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: dex-python-sdk
|
|
3
|
+
Version: 0.0.2
|
|
4
|
+
Requires-Dist: grpcio>=1.83.0
|
|
5
|
+
Requires-Dist: grpcio-status>=1.83.0
|
|
6
|
+
Requires-Dist: httpx==0.28.1
|
|
7
|
+
Requires-Dist: protobuf>=7.35.1
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
License-File: LEGACY_NOTICES.md
|
|
10
|
+
Summary: Python SDK for the Dex workflow engine
|
|
11
|
+
Author: Super Durable
|
|
12
|
+
License-Expression: LicenseRef-Super-Durable-1.0
|
|
13
|
+
Requires-Python: >=3.11
|
|
14
|
+
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
15
|
+
Project-URL: Homepage, https://github.com/superdurable/dex/tree/main/sdk-python
|
|
16
|
+
Project-URL: Repository, https://github.com/superdurable/dex
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
# Dex SDK for Python
|
|
20
|
+
|
|
21
|
+
Python SDK for [Dex workflow engine](https://github.com/superdurable/dex)
|
|
22
|
+
|
|
23
|
+
## New user contracts
|
|
24
|
+
|
|
25
|
+
The rewrite targets Python 3.11+ and exposes strongly typed workflow contracts
|
|
26
|
+
from `dex`. This phase includes definitions, attributes, channels, waits,
|
|
27
|
+
decisions, codecs, registry validation, synchronous client calls, and synchronous
|
|
28
|
+
worker handlers. Python owns its gRPC Client and Worker transport;
|
|
29
|
+
the shared Rust Core is used only for BlobCache.
|
|
30
|
+
|
|
31
|
+
```python
|
|
32
|
+
from datetime import timedelta
|
|
33
|
+
|
|
34
|
+
import dex
|
|
35
|
+
|
|
36
|
+
counter = dex.Attribute("counter", int)
|
|
37
|
+
counters_by_region = dex.AttributeMap("counters-by-region", int)
|
|
38
|
+
|
|
39
|
+
class Run(dex.Step[str]):
|
|
40
|
+
def wait_for(
|
|
41
|
+
self, context: dex.Context, input: str
|
|
42
|
+
) -> dex.Wait:
|
|
43
|
+
return dex.Wait.all_of(
|
|
44
|
+
dex.Timer.by_duration(timedelta(seconds=1))
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
def execute(
|
|
48
|
+
self, context: dex.Context, input: str
|
|
49
|
+
) -> dex.StepDecision:
|
|
50
|
+
return dex.graceful_complete(input)
|
|
51
|
+
|
|
52
|
+
class CounterFlow(dex.Flow[str]):
|
|
53
|
+
run = Run()
|
|
54
|
+
|
|
55
|
+
def get_flow_type(self) -> str:
|
|
56
|
+
return "Counter"
|
|
57
|
+
|
|
58
|
+
def get_steps(self) -> dex.StepList[str]:
|
|
59
|
+
return dex.StepList.start_step(self.run)
|
|
60
|
+
|
|
61
|
+
def get_persistence_schema(self) -> dex.PersistenceSchema:
|
|
62
|
+
return dex.PersistenceSchema.of(counter, counters_by_region)
|
|
63
|
+
|
|
64
|
+
@dex.rpc(name="Increment")
|
|
65
|
+
def increment(
|
|
66
|
+
self, context: dex.Context, input: int
|
|
67
|
+
) -> dex.RPCResult[int]:
|
|
68
|
+
return dex.RPCResult(input + 1)
|
|
69
|
+
|
|
70
|
+
flow = CounterFlow()
|
|
71
|
+
registry = dex.Registry((flow,))
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Registry derives codecs from declared Python types and handler annotations.
|
|
75
|
+
Built-in scalar types and dataclasses need no codec arguments. Register an
|
|
76
|
+
explicit codec only for a custom encoding or a type Registry cannot derive.
|
|
77
|
+
`PersistenceSchema.of(...)` accepts attributes and channels together and
|
|
78
|
+
partitions them by definition type.
|
|
79
|
+
|
|
80
|
+
Initial attributes retain their value types without a public wrapper class:
|
|
81
|
+
|
|
82
|
+
```python
|
|
83
|
+
options = (
|
|
84
|
+
dex.StartFlowOptions()
|
|
85
|
+
.with_attribute(counter, 1)
|
|
86
|
+
.with_attribute(counters_by_region, "us-west", 1)
|
|
87
|
+
)
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
pip install dex-python-sdk==0.0.2
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
See [samples](../examples/python) for use case examples.
|
|
95
|
+
|
|
96
|
+
## Requirements
|
|
97
|
+
|
|
98
|
+
- Python 3.11+
|
|
99
|
+
- [Dex server](https://github.com/superdurable/dex#how-to-use)
|
|
100
|
+
|
|
101
|
+
## Concepts
|
|
102
|
+
|
|
103
|
+
Applications implement two generic interfaces from [`dex.contracts`](dex/contracts/):
|
|
104
|
+
|
|
105
|
+
- `Flow[START_INPUT]` returns `StepList.start_step(...)`, followed by optional
|
|
106
|
+
`.other_steps(...)`, from one `get_steps()` method. The `StepList` generic
|
|
107
|
+
binds the Flow input to the starting Step input. Use `StepList.empty()` when
|
|
108
|
+
a Flow has no Steps.
|
|
109
|
+
- `Step[INPUT]` implements synchronous `execute` and optionally synchronous
|
|
110
|
+
`wait_for`.
|
|
111
|
+
|
|
112
|
+
`StepOptions.wait_for_method_timeout` and `execute_method_timeout` bound the
|
|
113
|
+
two handler calls. Timer and channel conditions determine how long a Step waits.
|
|
114
|
+
|
|
115
|
+
`Registry` validates every Flow, Step, RPC signature, durable name, lock, and
|
|
116
|
+
codec before Client or Worker startup. `Client` methods use these typed objects
|
|
117
|
+
instead of raw Flow, Step, or RPC strings.
|
|
118
|
+
|
|
119
|
+
The legacy IWF integration inventory is ported under
|
|
120
|
+
[`tests/integ`](tests/integ/README.md). Its 58 executable scenarios
|
|
121
|
+
exercise the same workflows, client operations, and assertions as the Java
|
|
122
|
+
suite against an isolated `dexcli dev` environment.
|
|
123
|
+
|
|
124
|
+
## Implementation status
|
|
125
|
+
|
|
126
|
+
The strongly typed contracts, registry, synchronous Client, Worker gRPC
|
|
127
|
+
service, and Rust-backed BlobCache are implemented. Python owns its gRPC
|
|
128
|
+
transport; the native bridge is limited to the shared BlobCache.
|
|
129
|
+
|
|
130
|
+
## Running dex-server locally
|
|
131
|
+
|
|
132
|
+
### Option 1: use docker compose
|
|
133
|
+
See [dex README](https://github.com/superdurable/dex#using-docker-image--docker-compose)
|
|
134
|
+
|
|
135
|
+
### Option 2: VSCode Dev Container
|
|
136
|
+
|
|
137
|
+
Dev Container is an easy way to get dex-server running locally. Follow these steps to launch a dev container:
|
|
138
|
+
- Install Docker, VSCode, and [VSCode Dev Container plugin](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers).
|
|
139
|
+
- Open the project in VSCode.
|
|
140
|
+
```bash
|
|
141
|
+
cd dex-python-sdk
|
|
142
|
+
code .
|
|
143
|
+
```
|
|
144
|
+
- 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.
|
|
145
|
+
- Once the dev container starts, dex-server will be listening on port 8801.
|
|
146
|
+
|
|
147
|
+
## How To Contribute
|
|
148
|
+
|
|
149
|
+
This project uses [uv](https://docs.astral.sh/uv/) for Python versions,
|
|
150
|
+
dependencies, virtual environments, locking, building, and publishing.
|
|
151
|
+
|
|
152
|
+
To install requirements:
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
uv sync --locked
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Run the complete Python SDK integration suite with an isolated Dex development
|
|
159
|
+
environment:
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
./run-integration-tests.sh
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
#### Update IDL
|
|
166
|
+
|
|
167
|
+
Edit [`protos/dex.proto`](../protos/dex.proto). Rename catalog: [`docs/design/idl-renames.md`](../docs/design/idl-renames.md).
|
|
168
|
+
|
|
169
|
+
#### Generate stubs from IDL
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
make -C ../protos proto-python
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Checked-in Python stubs land in `dex/dexpb/`.
|
|
176
|
+
#### Linting
|
|
177
|
+
|
|
178
|
+
To run linting for this project:
|
|
179
|
+
|
|
180
|
+
```bash
|
|
181
|
+
uv run --frozen pre-commit run --show-diff-on-failure --color=always --all-files
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
## Code of Conduct
|
|
185
|
+
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.)
|
|
186
|
+
|
|
187
|
+
## Publishing to PyPI
|
|
188
|
+
|
|
189
|
+
1. Bump `version` in `pyproject.toml`, refresh `uv.lock`, and update the `pip install` line above.
|
|
190
|
+
2. Run **Publish Python SDK to PyPI** manually without `publish` to validate all distributions.
|
|
191
|
+
3. Create a GitHub Release with tag `sdk-python/vX.Y.Z` (for example `sdk-python/v0.0.2`).
|
|
192
|
+
4. CI builds and smoke-tests Linux x86_64/ARM64, macOS x86_64/ARM64, and Windows x86_64 wheels, verifies the source distribution, and publishes them with `PYPI_TOKEN`.
|
|
193
|
+
|
|
194
|
+
A manual run publishes only from `main`, when its version matches `pyproject.toml` and `publish` is explicitly selected.
|
|
195
|
+
|
|
196
|
+
See [CONTRIBUTING.md](../CONTRIBUTING.md#releases-monorepo-tags) for monorepo tag conventions.
|
|
197
|
+
|
|
198
|
+
## License
|
|
199
|
+
|
|
200
|
+
[Super Durable Source License 1.0](LICENSE), with legacy portions under their
|
|
201
|
+
original terms as described in [LEGACY_NOTICES.md](LEGACY_NOTICES.md).
|
|
202
|
+
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
|
|
2
|
+
# Dex SDK for Python
|
|
3
|
+
|
|
4
|
+
Python SDK for [Dex workflow engine](https://github.com/superdurable/dex)
|
|
5
|
+
|
|
6
|
+
## New user contracts
|
|
7
|
+
|
|
8
|
+
The rewrite targets Python 3.11+ and exposes strongly typed workflow contracts
|
|
9
|
+
from `dex`. This phase includes definitions, attributes, channels, waits,
|
|
10
|
+
decisions, codecs, registry validation, synchronous client calls, and synchronous
|
|
11
|
+
worker handlers. Python owns its gRPC Client and Worker transport;
|
|
12
|
+
the shared Rust Core is used only for BlobCache.
|
|
13
|
+
|
|
14
|
+
```python
|
|
15
|
+
from datetime import timedelta
|
|
16
|
+
|
|
17
|
+
import dex
|
|
18
|
+
|
|
19
|
+
counter = dex.Attribute("counter", int)
|
|
20
|
+
counters_by_region = dex.AttributeMap("counters-by-region", int)
|
|
21
|
+
|
|
22
|
+
class Run(dex.Step[str]):
|
|
23
|
+
def wait_for(
|
|
24
|
+
self, context: dex.Context, input: str
|
|
25
|
+
) -> dex.Wait:
|
|
26
|
+
return dex.Wait.all_of(
|
|
27
|
+
dex.Timer.by_duration(timedelta(seconds=1))
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
def execute(
|
|
31
|
+
self, context: dex.Context, input: str
|
|
32
|
+
) -> dex.StepDecision:
|
|
33
|
+
return dex.graceful_complete(input)
|
|
34
|
+
|
|
35
|
+
class CounterFlow(dex.Flow[str]):
|
|
36
|
+
run = Run()
|
|
37
|
+
|
|
38
|
+
def get_flow_type(self) -> str:
|
|
39
|
+
return "Counter"
|
|
40
|
+
|
|
41
|
+
def get_steps(self) -> dex.StepList[str]:
|
|
42
|
+
return dex.StepList.start_step(self.run)
|
|
43
|
+
|
|
44
|
+
def get_persistence_schema(self) -> dex.PersistenceSchema:
|
|
45
|
+
return dex.PersistenceSchema.of(counter, counters_by_region)
|
|
46
|
+
|
|
47
|
+
@dex.rpc(name="Increment")
|
|
48
|
+
def increment(
|
|
49
|
+
self, context: dex.Context, input: int
|
|
50
|
+
) -> dex.RPCResult[int]:
|
|
51
|
+
return dex.RPCResult(input + 1)
|
|
52
|
+
|
|
53
|
+
flow = CounterFlow()
|
|
54
|
+
registry = dex.Registry((flow,))
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Registry derives codecs from declared Python types and handler annotations.
|
|
58
|
+
Built-in scalar types and dataclasses need no codec arguments. Register an
|
|
59
|
+
explicit codec only for a custom encoding or a type Registry cannot derive.
|
|
60
|
+
`PersistenceSchema.of(...)` accepts attributes and channels together and
|
|
61
|
+
partitions them by definition type.
|
|
62
|
+
|
|
63
|
+
Initial attributes retain their value types without a public wrapper class:
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
options = (
|
|
67
|
+
dex.StartFlowOptions()
|
|
68
|
+
.with_attribute(counter, 1)
|
|
69
|
+
.with_attribute(counters_by_region, "us-west", 1)
|
|
70
|
+
)
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
pip install dex-python-sdk==0.0.2
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
See [samples](../examples/python) for use case examples.
|
|
78
|
+
|
|
79
|
+
## Requirements
|
|
80
|
+
|
|
81
|
+
- Python 3.11+
|
|
82
|
+
- [Dex server](https://github.com/superdurable/dex#how-to-use)
|
|
83
|
+
|
|
84
|
+
## Concepts
|
|
85
|
+
|
|
86
|
+
Applications implement two generic interfaces from [`dex.contracts`](dex/contracts/):
|
|
87
|
+
|
|
88
|
+
- `Flow[START_INPUT]` returns `StepList.start_step(...)`, followed by optional
|
|
89
|
+
`.other_steps(...)`, from one `get_steps()` method. The `StepList` generic
|
|
90
|
+
binds the Flow input to the starting Step input. Use `StepList.empty()` when
|
|
91
|
+
a Flow has no Steps.
|
|
92
|
+
- `Step[INPUT]` implements synchronous `execute` and optionally synchronous
|
|
93
|
+
`wait_for`.
|
|
94
|
+
|
|
95
|
+
`StepOptions.wait_for_method_timeout` and `execute_method_timeout` bound the
|
|
96
|
+
two handler calls. Timer and channel conditions determine how long a Step waits.
|
|
97
|
+
|
|
98
|
+
`Registry` validates every Flow, Step, RPC signature, durable name, lock, and
|
|
99
|
+
codec before Client or Worker startup. `Client` methods use these typed objects
|
|
100
|
+
instead of raw Flow, Step, or RPC strings.
|
|
101
|
+
|
|
102
|
+
The legacy IWF integration inventory is ported under
|
|
103
|
+
[`tests/integ`](tests/integ/README.md). Its 58 executable scenarios
|
|
104
|
+
exercise the same workflows, client operations, and assertions as the Java
|
|
105
|
+
suite against an isolated `dexcli dev` environment.
|
|
106
|
+
|
|
107
|
+
## Implementation status
|
|
108
|
+
|
|
109
|
+
The strongly typed contracts, registry, synchronous Client, Worker gRPC
|
|
110
|
+
service, and Rust-backed BlobCache are implemented. Python owns its gRPC
|
|
111
|
+
transport; the native bridge is limited to the shared BlobCache.
|
|
112
|
+
|
|
113
|
+
## Running dex-server locally
|
|
114
|
+
|
|
115
|
+
### Option 1: use docker compose
|
|
116
|
+
See [dex README](https://github.com/superdurable/dex#using-docker-image--docker-compose)
|
|
117
|
+
|
|
118
|
+
### Option 2: VSCode Dev Container
|
|
119
|
+
|
|
120
|
+
Dev Container is an easy way to get dex-server running locally. Follow these steps to launch a dev container:
|
|
121
|
+
- Install Docker, VSCode, and [VSCode Dev Container plugin](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers).
|
|
122
|
+
- Open the project in VSCode.
|
|
123
|
+
```bash
|
|
124
|
+
cd dex-python-sdk
|
|
125
|
+
code .
|
|
126
|
+
```
|
|
127
|
+
- 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.
|
|
128
|
+
- Once the dev container starts, dex-server will be listening on port 8801.
|
|
129
|
+
|
|
130
|
+
## How To Contribute
|
|
131
|
+
|
|
132
|
+
This project uses [uv](https://docs.astral.sh/uv/) for Python versions,
|
|
133
|
+
dependencies, virtual environments, locking, building, and publishing.
|
|
134
|
+
|
|
135
|
+
To install requirements:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
uv sync --locked
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Run the complete Python SDK integration suite with an isolated Dex development
|
|
142
|
+
environment:
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
./run-integration-tests.sh
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
#### Update IDL
|
|
149
|
+
|
|
150
|
+
Edit [`protos/dex.proto`](../protos/dex.proto). Rename catalog: [`docs/design/idl-renames.md`](../docs/design/idl-renames.md).
|
|
151
|
+
|
|
152
|
+
#### Generate stubs from IDL
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
make -C ../protos proto-python
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Checked-in Python stubs land in `dex/dexpb/`.
|
|
159
|
+
#### Linting
|
|
160
|
+
|
|
161
|
+
To run linting for this project:
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
uv run --frozen pre-commit run --show-diff-on-failure --color=always --all-files
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
## Code of Conduct
|
|
168
|
+
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.)
|
|
169
|
+
|
|
170
|
+
## Publishing to PyPI
|
|
171
|
+
|
|
172
|
+
1. Bump `version` in `pyproject.toml`, refresh `uv.lock`, and update the `pip install` line above.
|
|
173
|
+
2. Run **Publish Python SDK to PyPI** manually without `publish` to validate all distributions.
|
|
174
|
+
3. Create a GitHub Release with tag `sdk-python/vX.Y.Z` (for example `sdk-python/v0.0.2`).
|
|
175
|
+
4. CI builds and smoke-tests Linux x86_64/ARM64, macOS x86_64/ARM64, and Windows x86_64 wheels, verifies the source distribution, and publishes them with `PYPI_TOKEN`.
|
|
176
|
+
|
|
177
|
+
A manual run publishes only from `main`, when its version matches `pyproject.toml` and `publish` is explicitly selected.
|
|
178
|
+
|
|
179
|
+
See [CONTRIBUTING.md](../CONTRIBUTING.md#releases-monorepo-tags) for monorepo tag conventions.
|
|
180
|
+
|
|
181
|
+
## License
|
|
182
|
+
|
|
183
|
+
[Super Durable Source License 1.0](LICENSE), with legacy portions under their
|
|
184
|
+
original terms as described in [LEGACY_NOTICES.md](LEGACY_NOTICES.md).
|