python-saga-orchestrator 0.2.4__tar.gz → 0.3.0__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 (92) hide show
  1. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/PKG-INFO +1 -1
  2. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/python_saga_orchestrator.egg-info/PKG-INFO +1 -1
  3. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/python_saga_orchestrator.egg-info/SOURCES.txt +1 -0
  4. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/saga_orchestrator/_version.py +2 -2
  5. python_saga_orchestrator-0.3.0/saga_orchestrator/domain/models/enums/base_str_enum.py +10 -0
  6. python_saga_orchestrator-0.3.0/saga_orchestrator/domain/models/enums/saga_status.py +17 -0
  7. python_saga_orchestrator-0.3.0/saga_orchestrator/domain/models/enums/saga_step_phase.py +9 -0
  8. python_saga_orchestrator-0.3.0/saga_orchestrator/domain/models/enums/saga_step_status.py +9 -0
  9. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/saga_orchestrator/domain/models/step.py +16 -7
  10. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/tests/integration/test_admin_api.py +3 -3
  11. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/tests/unit/test_input_context.py +3 -3
  12. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/tests/unit/test_step_type_resolution.py +11 -5
  13. python_saga_orchestrator-0.2.4/saga_orchestrator/domain/models/enums/saga_status.py +0 -15
  14. python_saga_orchestrator-0.2.4/saga_orchestrator/domain/models/enums/saga_step_phase.py +0 -7
  15. python_saga_orchestrator-0.2.4/saga_orchestrator/domain/models/enums/saga_step_status.py +0 -7
  16. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/.github/workflows/ci.yml +0 -0
  17. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/.github/workflows/publish.yml +0 -0
  18. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/.gitignore +0 -0
  19. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/Dockerfile +0 -0
  20. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/LICENSE +0 -0
  21. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/Makefile +0 -0
  22. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/README.md +0 -0
  23. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/docker-compose.yaml +0 -0
  24. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/examples/admin_skip.py +0 -0
  25. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/examples/common.py +0 -0
  26. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/examples/compensation_flow.py +0 -0
  27. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/examples/http_and_queue.py +0 -0
  28. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/examples/llm_deploy.py +0 -0
  29. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/examples/retry_recovery.py +0 -0
  30. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/pyproject.toml +0 -0
  31. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/python_saga_orchestrator.egg-info/dependency_links.txt +0 -0
  32. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/python_saga_orchestrator.egg-info/requires.txt +0 -0
  33. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/python_saga_orchestrator.egg-info/top_level.txt +0 -0
  34. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/saga_orchestrator/__init__.py +0 -0
  35. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/saga_orchestrator/admin/__init__.py +0 -0
  36. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/saga_orchestrator/admin/api.py +0 -0
  37. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/saga_orchestrator/core/__init__.py +0 -0
  38. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/saga_orchestrator/core/builder.py +0 -0
  39. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/saga_orchestrator/core/engine.py +0 -0
  40. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/saga_orchestrator/core/orchestrator.py +0 -0
  41. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/saga_orchestrator/core/repository.py +0 -0
  42. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/saga_orchestrator/domain/__init__.py +0 -0
  43. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/saga_orchestrator/domain/exceptions/__init__.py +0 -0
  44. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/saga_orchestrator/domain/exceptions/saga.py +0 -0
  45. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/saga_orchestrator/domain/mixins/__init__.py +0 -0
  46. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/saga_orchestrator/domain/mixins/saga_state.py +0 -0
  47. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/saga_orchestrator/domain/mixins/saga_step_histrory.py +0 -0
  48. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/saga_orchestrator/domain/mixins/types.py +0 -0
  49. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/saga_orchestrator/domain/models/__init__.py +0 -0
  50. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/saga_orchestrator/domain/models/builder.py +0 -0
  51. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/saga_orchestrator/domain/models/context.py +0 -0
  52. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/saga_orchestrator/domain/models/enums/__init__.py +0 -0
  53. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/saga_orchestrator/domain/models/notify.py +0 -0
  54. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/saga_orchestrator/domain/models/retry.py +0 -0
  55. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/saga_orchestrator/domain/models/saga_snapshot.py +0 -0
  56. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/saga_orchestrator/inbox/__init__.py +0 -0
  57. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/saga_orchestrator/inbox/contracts.py +0 -0
  58. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/saga_orchestrator/inbox/dispatcher.py +0 -0
  59. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/saga_orchestrator/inbox/models.py +0 -0
  60. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/saga_orchestrator/inbox/repository.py +0 -0
  61. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/saga_orchestrator/inbox/retry.py +0 -0
  62. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/saga_orchestrator/outbox/__init__.py +0 -0
  63. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/saga_orchestrator/outbox/contracts.py +0 -0
  64. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/saga_orchestrator/outbox/dispatcher.py +0 -0
  65. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/saga_orchestrator/outbox/event.py +0 -0
  66. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/saga_orchestrator/outbox/factory.py +0 -0
  67. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/saga_orchestrator/outbox/models.py +0 -0
  68. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/saga_orchestrator/outbox/repository.py +0 -0
  69. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/saga_orchestrator/outbox/retry.py +0 -0
  70. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/saga_orchestrator/outbox/serialization.py +0 -0
  71. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/setup.cfg +0 -0
  72. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/task.md +0 -0
  73. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/tests/__init__.py +0 -0
  74. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/tests/conftest.py +0 -0
  75. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/tests/integration/__init__.py +0 -0
  76. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/tests/integration/conftest.py +0 -0
  77. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/tests/integration/helpers.py +0 -0
  78. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/tests/integration/models.py +0 -0
  79. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/tests/integration/test_compensation_flow.py +0 -0
  80. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/tests/integration/test_context_persistence.py +0 -0
  81. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/tests/integration/test_core_flow.py +0 -0
  82. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/tests/integration/test_inbox_flow.py +0 -0
  83. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/tests/integration/test_lifecycle_hooks.py +0 -0
  84. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/tests/integration/test_notification_flow.py +0 -0
  85. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/tests/integration/test_outbox_flow.py +0 -0
  86. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/tests/integration/test_repository.py +0 -0
  87. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/tests/unit/__init__.py +0 -0
  88. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/tests/unit/test_builder.py +0 -0
  89. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/tests/unit/test_inbox_extensibility.py +0 -0
  90. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/tests/unit/test_orchestrator_helpers.py +0 -0
  91. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/tests/unit/test_outbox_extensibility.py +0 -0
  92. {python_saga_orchestrator-0.2.4 → python_saga_orchestrator-0.3.0}/tests/unit/test_retry.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-saga-orchestrator
3
- Version: 0.2.4
3
+ Version: 0.3.0
4
4
  Summary: Lightweight embedded saga orchestrator for asyncio Python services
5
5
  Author-email: Maxim Vasilyev <mayxis@inbox.ru>
6
6
  License-Expression: MIT
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: python-saga-orchestrator
3
- Version: 0.2.4
3
+ Version: 0.3.0
4
4
  Summary: Lightweight embedded saga orchestrator for asyncio Python services
5
5
  Author-email: Maxim Vasilyev <mayxis@inbox.ru>
6
6
  License-Expression: MIT
@@ -43,6 +43,7 @@ saga_orchestrator/domain/models/retry.py
43
43
  saga_orchestrator/domain/models/saga_snapshot.py
44
44
  saga_orchestrator/domain/models/step.py
45
45
  saga_orchestrator/domain/models/enums/__init__.py
46
+ saga_orchestrator/domain/models/enums/base_str_enum.py
46
47
  saga_orchestrator/domain/models/enums/saga_status.py
47
48
  saga_orchestrator/domain/models/enums/saga_step_phase.py
48
49
  saga_orchestrator/domain/models/enums/saga_step_status.py
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '0.2.4'
22
- __version_tuple__ = version_tuple = (0, 2, 4)
21
+ __version__ = version = '0.3.0'
22
+ __version_tuple__ = version_tuple = (0, 3, 0)
23
23
 
24
24
  __commit_id__ = commit_id = None
@@ -0,0 +1,10 @@
1
+ from enum import StrEnum
2
+
3
+
4
+ class BaseStrEnum(StrEnum):
5
+ @staticmethod
6
+ def _generate_next_value_(name, start, count, last_values) -> str:
7
+ """
8
+ Return the upper-cased version of the member name.
9
+ """
10
+ return name.upper()
@@ -0,0 +1,17 @@
1
+ from enum import auto
2
+
3
+ from .base_str_enum import BaseStrEnum
4
+
5
+
6
+ class SagaStatus(BaseStrEnum):
7
+ RUNNING = auto()
8
+ SUSPENDED = auto()
9
+ FAILED = auto()
10
+ COMPENSATING = auto()
11
+ COMPLETED = auto()
12
+ COMPENSATING_SUSPENDED = auto()
13
+ COMPENSATED = auto()
14
+
15
+ @property
16
+ def is_terminal(self) -> bool:
17
+ return self in {self.FAILED, self.COMPLETED, self.COMPENSATED}
@@ -0,0 +1,9 @@
1
+ from enum import auto
2
+
3
+ from .base_str_enum import BaseStrEnum
4
+
5
+
6
+ class SagaStepPhase(BaseStrEnum):
7
+ COMPENSATE = auto()
8
+ SUCCESS = auto()
9
+ EXECUTE = auto()
@@ -0,0 +1,9 @@
1
+ from enum import auto
2
+
3
+ from .base_str_enum import BaseStrEnum
4
+
5
+
6
+ class SagaStepStatus(BaseStrEnum):
7
+ SUCCESS = auto()
8
+ ERROR = auto()
9
+ WAITING = auto()
@@ -119,19 +119,24 @@ class BaseStep(Generic[InputModelT, OutputModelT]):
119
119
 
120
120
  concrete_args = get_args(generic_base)
121
121
  if not concrete_args or any(isinstance(arg, TypeVar) for arg in concrete_args):
122
- raise TypeValidationError(f"Step '{cls.__name__}' inherits from a generic Step "
123
- "but was not parameterized with concrete Input/Output models.")
122
+ raise TypeValidationError(
123
+ f"Step '{cls.__name__}' inherits from a generic Step "
124
+ "but was not parameterized with concrete Input/Output models."
125
+ )
124
126
 
125
127
  concrete_input_model, concrete_output_model = concrete_args
126
128
  try:
127
- hints = get_type_hints(cls.execute, globalns=inspect.getmodule(cls).__dict__, include_extras=True)
129
+ hints = get_type_hints(
130
+ cls.execute,
131
+ globalns=inspect.getmodule(cls).__dict__,
132
+ include_extras=True,
133
+ )
128
134
  except (AttributeError, NameError) as e:
129
- raise TypeValidationError(
135
+ raise TypeValidationError(
130
136
  f"Could not resolve type hints for '{cls.__name__}.execute'. "
131
137
  f"Ensure all types are correctly imported. Original error: {e}"
132
138
  )
133
139
 
134
-
135
140
  if "inp" not in hints or "return" not in hints:
136
141
  raise TypeValidationError(
137
142
  f"Step '{cls.__name__}' must type annotate execute(inp) and return type"
@@ -144,7 +149,9 @@ class BaseStep(Generic[InputModelT, OutputModelT]):
144
149
  input_model = input_annotation
145
150
 
146
151
  return_annotation = hints["return"]
147
- output_model = cls._resolve_output_model(return_annotation, concrete_output_model)
152
+ output_model = cls._resolve_output_model(
153
+ return_annotation, concrete_output_model
154
+ )
148
155
  if not (inspect.isclass(input_model) and issubclass(input_model, BaseModel)):
149
156
  raise TypeValidationError(
150
157
  f"Step '{cls.__name__}' input must inherit from pydantic BaseModel"
@@ -153,7 +160,9 @@ class BaseStep(Generic[InputModelT, OutputModelT]):
153
160
  cls.output_model = output_model
154
161
 
155
162
  @staticmethod
156
- def _resolve_output_model(annotation: Any, concrete_model: type[BaseModel] | None = None) -> type[BaseModel]:
163
+ def _resolve_output_model(
164
+ annotation: Any, concrete_model: type[BaseModel] | None = None
165
+ ) -> type[BaseModel]:
157
166
  def find_model_in_args(args_tuple: tuple) -> list[type[BaseModel]]:
158
167
  candidates = []
159
168
  for arg in args_tuple:
@@ -58,7 +58,7 @@ async def test_admin_retry_rejects_failed_saga_after_compensation(session_maker)
58
58
  )
59
59
  state = await admin.get_saga(saga_id)
60
60
  assert state.status == SagaStatus.COMPENSATED
61
- assert any(entry.phase == "compensate" for entry in state.step_history)
61
+ assert any(entry.phase == "COMPENSATE" for entry in state.step_history)
62
62
 
63
63
  with pytest.raises(SagaStateError):
64
64
  await admin.retry_step(saga_id)
@@ -150,7 +150,7 @@ async def test_admin_compensate_rolls_back_suspended_saga(session_maker):
150
150
  state_after = await admin.get_saga(saga_id)
151
151
  assert state_after.status == SagaStatus.COMPENSATED
152
152
  assert compensating_step.compensated is True
153
- assert any(entry.phase == "compensate" for entry in state_after.step_history)
153
+ assert any(entry.phase == "COMPENSATE" for entry in state_after.step_history)
154
154
 
155
155
 
156
156
  @pytest.mark.asyncio
@@ -225,7 +225,7 @@ async def test_get_admin_snapshot_returns(session_maker):
225
225
  assert isinstance(admin_snapshot.step_history, list)
226
226
  assert len(admin_snapshot.step_history) == 1
227
227
  assert admin_snapshot.step_history[0].step_name == "AddOneStep"
228
- assert admin_snapshot.step_history[0].status == "success"
228
+ assert admin_snapshot.step_history[0].status == "SUCCESS"
229
229
 
230
230
 
231
231
  @pytest.mark.asyncio
@@ -81,6 +81,6 @@ def test_input_context_properties_parametrized(
81
81
  )
82
82
 
83
83
  assert input_ctx.latest_event_type == expected_type, f"Failed on test: {test_id}"
84
- assert (
85
- input_ctx.latest_event_payload == expected_payload
86
- ), f"Failed on test: {test_id}"
84
+ assert input_ctx.latest_event_payload == expected_payload, (
85
+ f"Failed on test: {test_id}"
86
+ )
@@ -40,7 +40,6 @@ class StepAwaitEvent:
40
40
  event_types: tuple[str, ...] | None = None
41
41
 
42
42
 
43
-
44
43
  IntermediateInputT = TypeVar("IntermediateInputT", bound=BaseModel)
45
44
  IntermediateOutputT = TypeVar("IntermediateOutputT", bound=BaseModel)
46
45
 
@@ -48,18 +47,19 @@ IntermediateOutputT = TypeVar("IntermediateOutputT", bound=BaseModel)
48
47
  class AbstractIntermediateStep(
49
48
  BaseStep[IntermediateInputT, IntermediateOutputT],
50
49
  ABC,
51
- Generic[IntermediateInputT, IntermediateOutputT]
50
+ Generic[IntermediateInputT, IntermediateOutputT],
52
51
  ):
53
52
  @abstractmethod
54
53
  def some_abstract_method(self):
55
54
  pass
56
55
 
57
- async def execute(self, inp: IntermediateInputT) -> IntermediateOutputT | StepAwaitEvent:
56
+ async def execute(
57
+ self, inp: IntermediateInputT
58
+ ) -> IntermediateOutputT | StepAwaitEvent:
58
59
  pass
59
60
 
60
61
 
61
62
  class TestTypeResolution:
62
-
63
63
  def test_indirect_inheritance_resolves_types_correctly(self):
64
64
  """
65
65
  GIVEN a concrete step class inheriting from a generic abstract step
@@ -97,6 +97,7 @@ class TestTypeResolution:
97
97
  THEN TypeValidationError should be raised.
98
98
  """
99
99
  with pytest.raises(TypeValidationError, match="must type annotate execute"):
100
+
100
101
  class FaultyStep(BaseStep[InputModelA, OutputModelA]):
101
102
  # `inp` не аннотирован
102
103
  async def execute(self, inp) -> OutputModelA:
@@ -114,6 +115,7 @@ class TestTypeResolution:
114
115
  pass
115
116
 
116
117
  with pytest.raises(TypeValidationError, match="Could not resolve type hints"):
118
+
117
119
  class FaultyStep(BaseStep[InputModelA, OutputModelA]):
118
120
  async def execute(self, inp: NotAModel) -> OutputModelA:
119
121
  pass
@@ -124,7 +126,11 @@ class TestTypeResolution:
124
126
  WHEN the class is defined
125
127
  THEN TypeValidationError should be raised by our custom logic.
126
128
  """
127
- with pytest.raises(TypeValidationError, match="inherits from a generic Step but was not parameterized with concrete Input/Output models"):
129
+ with pytest.raises(
130
+ TypeValidationError,
131
+ match="inherits from a generic Step but was not parameterized with concrete Input/Output models",
132
+ ):
133
+
128
134
  class UnparameterizedStep(AbstractIntermediateStep):
129
135
  def some_abstract_method(self):
130
136
  pass
@@ -1,15 +0,0 @@
1
- from enum import StrEnum
2
-
3
-
4
- class SagaStatus(StrEnum):
5
- RUNNING = "RUNNING"
6
- SUSPENDED = "SUSPENDED"
7
- FAILED = "FAILED"
8
- COMPENSATING = "COMPENSATING"
9
- COMPLETED = "COMPLETED"
10
- COMPENSATING_SUSPENDED = "COMPENSATING_SUSPENDED"
11
- COMPENSATED = "COMPENSATED"
12
-
13
- @property
14
- def is_terminal(self) -> bool:
15
- return self in {self.FAILED, self.COMPLETED, self.COMPENSATED}
@@ -1,7 +0,0 @@
1
- from enum import StrEnum, auto
2
-
3
-
4
- class SagaStepPhase(StrEnum):
5
- COMPENSATE = auto()
6
- SUCCESS = auto()
7
- EXECUTE = auto()
@@ -1,7 +0,0 @@
1
- from enum import StrEnum, auto
2
-
3
-
4
- class SagaStepStatus(StrEnum):
5
- SUCCESS = auto()
6
- ERROR = auto()
7
- WAITING = auto()