orchestrator-core 3.1.1__py3-none-any.whl → 3.1.2rc3__py3-none-any.whl

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.
orchestrator/__init__.py CHANGED
@@ -13,7 +13,7 @@
13
13
 
14
14
  """This is the orchestrator workflow engine."""
15
15
 
16
- __version__ = "3.1.1"
16
+ __version__ = "3.1.2rc3"
17
17
 
18
18
  from orchestrator.app import OrchestratorCore
19
19
  from orchestrator.settings import app_settings
@@ -58,6 +58,7 @@ from orchestrator.services.processes import (
58
58
  load_process,
59
59
  resume_process,
60
60
  start_process,
61
+ update_awaiting_process_progress,
61
62
  )
62
63
  from orchestrator.services.settings import get_engine_settings
63
64
  from orchestrator.settings import app_settings
@@ -197,6 +198,28 @@ def continue_awaiting_process_endpoint(
197
198
  raise_status(HTTPStatus.NOT_FOUND, str(e))
198
199
 
199
200
 
201
+ @router.post(
202
+ "/{process_id}/callback/{token}/progress",
203
+ response_model=None,
204
+ status_code=HTTPStatus.OK,
205
+ dependencies=[Depends(check_global_lock, use_cache=False)],
206
+ )
207
+ def update_progress_on_awaiting_process_endpoint(
208
+ process_id: UUID,
209
+ token: str,
210
+ data: str | State = Body(...),
211
+ ) -> None:
212
+ process = _get_process(process_id)
213
+
214
+ if process.last_status != ProcessStatus.AWAITING_CALLBACK:
215
+ raise_status(HTTPStatus.CONFLICT, "This process is not in an awaiting state.")
216
+
217
+ try:
218
+ update_awaiting_process_progress(process, token=token, data=data)
219
+ except AssertionError as exc:
220
+ raise_status(HTTPStatus.NOT_FOUND, str(exc))
221
+
222
+
200
223
  @router.put(
201
224
  "/resume-all", response_model=ProcessResumeAllSchema, dependencies=[Depends(check_global_lock, use_cache=False)]
202
225
  )
orchestrator/db/models.py CHANGED
@@ -92,7 +92,7 @@ class InputStateTable(BaseModel):
92
92
 
93
93
  input_state_id = mapped_column(UUIDType, primary_key=True, server_default=text("uuid_generate_v4()"), index=True)
94
94
  process_id = mapped_column("pid", UUIDType, ForeignKey("processes.pid"), nullable=False)
95
- input_state = mapped_column(pg.JSONB(), nullable=False) # type: ignore
95
+ input_state = mapped_column(pg.JSONB(), nullable=False)
96
96
  input_time = mapped_column(UtcTimestamp, server_default=text("current_timestamp()"), nullable=False)
97
97
  input_type = mapped_column(Enum(InputType), nullable=False)
98
98
 
@@ -137,7 +137,7 @@ class ProcessStepTable(BaseModel):
137
137
  )
138
138
  name = mapped_column(String(), nullable=False)
139
139
  status = mapped_column(String(50), nullable=False)
140
- state = mapped_column(pg.JSONB(), nullable=False) # type: ignore
140
+ state = mapped_column(pg.JSONB(), nullable=False)
141
141
  created_by = mapped_column(String(255), nullable=True)
142
142
  executed_at = mapped_column(UtcTimestamp, server_default=text("statement_timestamp()"), nullable=False)
143
143
  commit_hash = mapped_column(String(40), nullable=True, default=GIT_COMMIT_HASH)
@@ -642,7 +642,7 @@ class SubscriptionMetadataTable(BaseModel):
642
642
  primary_key=True,
643
643
  index=True,
644
644
  )
645
- metadata_ = mapped_column("metadata", pg.JSONB(), nullable=False) # type: ignore
645
+ metadata_ = mapped_column("metadata", pg.JSONB(), nullable=False)
646
646
 
647
647
  @staticmethod
648
648
  def find_by_subscription_id(subscription_id: str) -> SubscriptionMetadataTable | None:
@@ -651,6 +651,8 @@ class SubscriptionMetadataTable(BaseModel):
651
651
 
652
652
  class SubscriptionSearchView(BaseModel):
653
653
  __tablename__ = "subscriptions_search"
654
+ __table_args__ = {"info": {"materialized_view": True}}
655
+
654
656
  subscription_id = mapped_column(
655
657
  UUIDType, ForeignKey("subscriptions.subscription_id"), nullable=False, index=True, primary_key=True
656
658
  )
@@ -41,6 +41,14 @@ target_metadata = BaseModel.metadata
41
41
  # ... etc.
42
42
 
43
43
 
44
+ def include_object(object, name, type_, reflected, compare_to): # type: ignore
45
+ """Determines if an object should be included."""
46
+
47
+ if type_ == "table" and object.info.get("materialized_view", False):
48
+ return False
49
+ return True
50
+
51
+
44
52
  def run_migrations_offline() -> None:
45
53
  """Run migrations in 'offline' mode.
46
54
 
@@ -55,7 +63,11 @@ def run_migrations_offline() -> None:
55
63
  """
56
64
  url = config.get_main_option("sqlalchemy.url")
57
65
  context.configure(
58
- url=url, target_metadata=target_metadata, literal_binds=True, dialect_opts={"paramstyle": "named"}
66
+ url=url,
67
+ target_metadata=target_metadata,
68
+ literal_binds=True,
69
+ dialect_opts={"paramstyle": "named"},
70
+ include_object=include_object,
59
71
  )
60
72
 
61
73
  with context.begin_transaction():
@@ -90,6 +102,7 @@ def run_migrations_online() -> None:
90
102
  target_metadata=target_metadata,
91
103
  process_revision_directives=process_revision_directives,
92
104
  compare_type=True,
105
+ include_object=include_object,
93
106
  )
94
107
 
95
108
  try:
@@ -157,7 +157,7 @@ def upgrade() -> None:
157
157
  sa.Column("pid", sqlalchemy_utils.types.uuid.UUIDType(), nullable=False),
158
158
  sa.Column("name", sa.String(), nullable=False),
159
159
  sa.Column("status", sa.String(length=50), nullable=False),
160
- sa.Column("state", postgresql.JSONB(astext_type=sa.Text()), nullable=False), # type: ignore
160
+ sa.Column("state", postgresql.JSONB(astext_type=sa.Text()), nullable=False),
161
161
  sa.Column("created_by", sa.String(length=255), nullable=True),
162
162
  sa.Column(
163
163
  "executed_at",
@@ -29,7 +29,7 @@ def upgrade() -> None:
29
29
  nullable=False,
30
30
  index=True,
31
31
  ),
32
- sa.Column("metadata", postgresql.JSONB(astext_type=sa.Text()), nullable=False), # type: ignore
32
+ sa.Column("metadata", postgresql.JSONB(astext_type=sa.Text()), nullable=False),
33
33
  sa.ForeignKeyConstraint(["subscription_id"], ["subscriptions.subscription_id"], ondelete="CASCADE"),
34
34
  )
35
35
 
@@ -31,7 +31,7 @@ def upgrade() -> None:
31
31
  nullable=False,
32
32
  ),
33
33
  sa.Column("pid", sqlalchemy_utils.types.uuid.UUIDType(), nullable=False),
34
- sa.Column("input_state", postgresql.JSONB(astext_type=sa.Text()), nullable=False), # type: ignore
34
+ sa.Column("input_state", postgresql.JSONB(astext_type=sa.Text()), nullable=False),
35
35
  sa.Column(
36
36
  "input_time",
37
37
  db.models.UtcTimestamp(timezone=True),
@@ -43,9 +43,10 @@ from orchestrator.targets import Target
43
43
  from orchestrator.types import BroadcastFunc
44
44
  from orchestrator.utils.datetime import nowtz
45
45
  from orchestrator.utils.errors import error_state_to_dict
46
- from orchestrator.websocket import broadcast_invalidate_status_counts
46
+ from orchestrator.websocket import broadcast_invalidate_status_counts, broadcast_process_update_to_websocket
47
47
  from orchestrator.workflow import (
48
48
  CALLBACK_TOKEN_KEY,
49
+ DEFAULT_CALLBACK_PROGRESS_KEY,
49
50
  Failed,
50
51
  ProcessStat,
51
52
  ProcessStatus,
@@ -566,6 +567,39 @@ def resume_process(
566
567
  return resume_func(process, user_inputs=user_inputs, user=user, broadcast_func=broadcast_func)
567
568
 
568
569
 
570
+ def ensure_correct_callback_token(pstat: ProcessStat, *, token: str) -> None:
571
+ """Ensure that a callback token matches the expected value in state.
572
+
573
+ Args:
574
+ pstat: ProcessStat of process.
575
+ token: The token which was generated for the process.
576
+
577
+ Raises:
578
+ AssertionError: if the supplied token does not match the generated process token.
579
+
580
+ """
581
+ state = pstat.state.unwrap()
582
+
583
+ # Check if the token matches
584
+ token_from_state = state.get(CALLBACK_TOKEN_KEY)
585
+ if token != token_from_state:
586
+ raise AssertionError("Invalid token")
587
+
588
+
589
+ def replace_current_step_state(process: ProcessTable, *, new_state: State) -> None:
590
+ """Replace the state of the current step in a process.
591
+
592
+ Args:
593
+ process: Process from database
594
+ new_state: The new state
595
+
596
+ """
597
+ current_step = process.steps[-1]
598
+ current_step.state = new_state
599
+ db.session.add(current_step)
600
+ db.session.commit()
601
+
602
+
569
603
  def continue_awaiting_process(
570
604
  process: ProcessTable,
571
605
  *,
@@ -589,10 +623,7 @@ def continue_awaiting_process(
589
623
  pstat = load_process(process)
590
624
  state = pstat.state.unwrap()
591
625
 
592
- # Check if the token matches
593
- token_from_state = state.get(CALLBACK_TOKEN_KEY)
594
- if token != token_from_state:
595
- raise AssertionError("Invalid token")
626
+ ensure_correct_callback_token(pstat, token=token)
596
627
 
597
628
  # We need to pass the callback data to the worker executor. Currently, this is not supported.
598
629
  # Therefore, we update the step state in the db and kick-off resume_workflow
@@ -600,16 +631,47 @@ def continue_awaiting_process(
600
631
  result_key = state.get("__callback_result_key", "callback_result")
601
632
  state = {**state, result_key: input_data}
602
633
 
603
- current_step = process.steps[-1]
604
- current_step.state = state
605
- db.session.add(current_step)
606
- db.session.commit()
634
+ replace_current_step_state(process, new_state=state)
607
635
 
608
636
  # Continue the workflow
609
637
  resume_func = get_execution_context()["resume"]
610
638
  return resume_func(process, broadcast_func=broadcast_func)
611
639
 
612
640
 
641
+ def update_awaiting_process_progress(
642
+ process: ProcessTable,
643
+ *,
644
+ token: str,
645
+ data: str | State,
646
+ ) -> UUID:
647
+ """Update progress for a process awaiting data from a callback.
648
+
649
+ Args:
650
+ process: Process from database
651
+ token: The token which was generated for the process. This must match.
652
+ data: Progress data posted to the callback
653
+
654
+ Returns:
655
+ process id
656
+
657
+ Raises:
658
+ AssertionError: if the supplied token does not match the generated process token.
659
+
660
+ """
661
+ pstat = load_process(process)
662
+
663
+ ensure_correct_callback_token(pstat, token=token)
664
+
665
+ state = pstat.state.unwrap()
666
+ progress_key = state.get(DEFAULT_CALLBACK_PROGRESS_KEY, "callback_progress")
667
+ state = {**state, progress_key: data} | {"__remove_keys": [progress_key]}
668
+
669
+ replace_current_step_state(process, new_state=state)
670
+ broadcast_process_update_to_websocket(process.process_id)
671
+
672
+ return process.process_id
673
+
674
+
613
675
  async def _async_resume_processes(
614
676
  processes: Sequence[ProcessTable],
615
677
  user_name: str,
@@ -150,65 +150,85 @@ def _build_arguments(func: StepFunc | InputStepFunc, state: State) -> list: # n
150
150
 
151
151
  Raises:
152
152
  KeyError: if requested argument is not in the state, or cannot be reconstructed as an initial domain model.
153
+ ValueError: if requested argument cannot be converted to the expected type.
153
154
 
154
155
  """
156
+
155
157
  sig = inspect.signature(func)
158
+ if not sig.parameters:
159
+ return []
160
+
161
+ def _convert_to_uuid(v: Any) -> UUID:
162
+ """Converts the value to a UUID instance if it is not already one."""
163
+ return v if isinstance(v, UUID) else UUID(v)
164
+
156
165
  arguments: list[Any] = []
157
- if sig.parameters:
158
- for name, param in sig.parameters.items():
159
- # Ignore dynamic arguments. Mostly need to deal with `const`
160
- if param.kind in (inspect.Parameter.VAR_POSITIONAL, inspect.Parameter.VAR_KEYWORD):
161
- logger.warning("*args and **kwargs are not supported as step params")
162
- continue
163
-
164
- # If we find an argument named "state" we use the whole state as argument to
165
- # This is mainly to be backward compatible with code that needs the whole state...
166
- # TODO: Remove this construction
167
- if name == "state":
168
- arguments.append(state)
169
- continue
170
-
171
- # Workaround for the fact that you can't call issubclass on typing types
166
+ for name, param in sig.parameters.items():
167
+ # Ignore dynamic arguments. Mostly need to deal with `const`
168
+ if param.kind in (inspect.Parameter.VAR_POSITIONAL, inspect.Parameter.VAR_KEYWORD):
169
+ logger.warning("*args and **kwargs are not supported as step params")
170
+ continue
171
+
172
+ # If we find an argument named "state" we use the whole state as argument to
173
+ # This is mainly to be backward compatible with code that needs the whole state...
174
+ # TODO: Remove this construction
175
+ if name == "state":
176
+ arguments.append(state)
177
+ continue
178
+
179
+ # Workaround for the fact that you can't call issubclass on typing types
180
+ try:
181
+ is_subscription_model_type = issubclass(param.annotation, SubscriptionModel)
182
+ except Exception:
183
+ is_subscription_model_type = False
184
+
185
+ if is_subscription_model_type:
186
+ subscription_id = _get_sub_id(state.get(name))
187
+ if subscription_id:
188
+ sub_mod = param.annotation.from_subscription(subscription_id)
189
+ arguments.append(sub_mod)
190
+ else:
191
+ logger.error("Could not find key in state.", key=name, state=state)
192
+ raise KeyError(f"Could not find key '{name}' in state.")
193
+ elif is_list_type(param.annotation, SubscriptionModel):
194
+ subscription_ids = [_get_sub_id(item) for item in state.get(name, [])]
195
+ # Actual type is first argument from list type
196
+ if (actual_type := get_args(param.annotation)[0]) == Any:
197
+ raise ValueError(
198
+ f"Step function argument '{param.name}' cannot be serialized from database with type 'Any'"
199
+ )
200
+ subscriptions = [actual_type.from_subscription(subscription_id) for subscription_id in subscription_ids]
201
+ arguments.append(subscriptions)
202
+ elif is_optional_type(param.annotation, SubscriptionModel):
203
+ subscription_id = _get_sub_id(state.get(name))
204
+ if subscription_id:
205
+ # Actual type is first argument from optional type
206
+ sub_mod = get_args(param.annotation)[0].from_subscription(subscription_id)
207
+ arguments.append(sub_mod)
208
+ else:
209
+ arguments.append(None)
210
+ elif param.default is not inspect.Parameter.empty:
211
+ arguments.append(state.get(name, param.default))
212
+ else:
172
213
  try:
173
- is_subscription_model_type = issubclass(param.annotation, SubscriptionModel)
174
- except Exception:
175
- is_subscription_model_type = False
176
-
177
- if is_subscription_model_type:
178
- subscription_id = _get_sub_id(state.get(name))
179
- if subscription_id:
180
- sub_mod = param.annotation.from_subscription(subscription_id)
181
- arguments.append(sub_mod)
182
- else:
183
- logger.error("Could not find key in state.", key=name, state=state)
184
- raise KeyError(f"Could not find key '{name}' in state.")
185
- elif is_list_type(param.annotation, SubscriptionModel):
186
- subscription_ids = map(_get_sub_id, state.get(name, []))
187
- # Actual type is first argument from list type
188
- if (actual_type := get_args(param.annotation)[0]) == Any:
189
- raise ValueError(
190
- f"Step function argument '{param.name}' cannot be serialized from database with type 'Any'"
191
- )
192
- subscriptions = [actual_type.from_subscription(subscription_id) for subscription_id in subscription_ids]
193
- arguments.append(subscriptions)
194
- elif is_optional_type(param.annotation, SubscriptionModel):
195
- subscription_id = _get_sub_id(state.get(name))
196
- if subscription_id:
197
- # Actual type is first argument from optional type
198
- sub_mod = get_args(param.annotation)[0].from_subscription(subscription_id)
199
- arguments.append(sub_mod)
214
+ value = state[name]
215
+ if param.annotation == UUID:
216
+ arguments.append(_convert_to_uuid(value))
217
+ elif is_list_type(param.annotation, UUID):
218
+ arguments.append([_convert_to_uuid(item) for item in value])
219
+ elif is_optional_type(param.annotation, UUID):
220
+ arguments.append(None if value is None else _convert_to_uuid(value))
200
221
  else:
201
- arguments.append(None)
202
- elif param.default is not inspect.Parameter.empty:
203
- arguments.append(state.get(name, param.default))
204
- else:
205
- try:
206
- arguments.append(state[name])
207
- except KeyError as key_error:
208
- logger.error("Could not find key in state.", key=name, state=state)
209
- raise KeyError(
210
- f"Could not find key '{name}' in state. for function {func.__module__}.{func.__qualname__}"
211
- ) from key_error
222
+ arguments.append(value)
223
+ except KeyError as key_error:
224
+ logger.error("Could not find key in state.", key=name, state=state)
225
+ raise KeyError(
226
+ f"Could not find key '{name}' in state. for function {func.__module__}.{func.__qualname__}"
227
+ ) from key_error
228
+ except ValueError as value_error:
229
+ logger.error("Could not convert value to expected type.", key=name, state=state, value=state[name])
230
+ raise ValueError(f"Could not convert value '{state[name]}' to {param.annotation}") from value_error
231
+
212
232
  return arguments
213
233
 
214
234
 
orchestrator/workflow.py CHANGED
@@ -69,6 +69,7 @@ step_log_fn_var: contextvars.ContextVar[StepLogFuncInternal] = contextvars.Conte
69
69
 
70
70
  DEFAULT_CALLBACK_ROUTE_KEY = "callback_route"
71
71
  CALLBACK_TOKEN_KEY = "__callback_token" # noqa: S105
72
+ DEFAULT_CALLBACK_PROGRESS_KEY = "callback_progress" # noqa: S105
72
73
 
73
74
 
74
75
  @runtime_checkable
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: orchestrator-core
3
- Version: 3.1.1
3
+ Version: 3.1.2rc3
4
4
  Summary: This is the orchestrator workflow engine.
5
5
  Requires-Python: >=3.11,<3.14
6
6
  Classifier: Intended Audience :: Information Technology
@@ -28,7 +28,7 @@ Classifier: Programming Language :: Python :: 3.11
28
28
  Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers
29
29
  Classifier: Topic :: Internet :: WWW/HTTP
30
30
  License-File: LICENSE
31
- Requires-Dist: alembic==1.14.1
31
+ Requires-Dist: alembic==1.15.1
32
32
  Requires-Dist: anyio>=3.7.0
33
33
  Requires-Dist: click==8.*
34
34
  Requires-Dist: deprecated
@@ -37,18 +37,18 @@ Requires-Dist: fastapi~=0.115.2
37
37
  Requires-Dist: fastapi-etag==0.4.0
38
38
  Requires-Dist: more-itertools~=10.6.0
39
39
  Requires-Dist: itsdangerous
40
- Requires-Dist: Jinja2==3.1.5
40
+ Requires-Dist: Jinja2==3.1.6
41
41
  Requires-Dist: orjson==3.10.15
42
- Requires-Dist: psycopg[binary]==3.2.5
43
- Requires-Dist: pydantic[email]~=2.10.6
42
+ Requires-Dist: psycopg[binary]==3.2.6
43
+ Requires-Dist: pydantic[email]~=2.8.2
44
44
  Requires-Dist: pydantic-settings~=2.8.0
45
45
  Requires-Dist: python-dateutil==2.8.2
46
46
  Requires-Dist: python-rapidjson>=1.18,<1.21
47
47
  Requires-Dist: pytz==2025.1
48
- Requires-Dist: redis==5.0.3
48
+ Requires-Dist: redis==5.1.1
49
49
  Requires-Dist: schedule==1.1.0
50
50
  Requires-Dist: sentry-sdk[fastapi]~=2.22.0
51
- Requires-Dist: SQLAlchemy==2.0.38
51
+ Requires-Dist: SQLAlchemy==2.0.39
52
52
  Requires-Dist: SQLAlchemy-Utils==0.41.2
53
53
  Requires-Dist: structlog
54
54
  Requires-Dist: typer==0.15.2
@@ -1,4 +1,4 @@
1
- orchestrator/__init__.py,sha256=gaUFW9gqwFRHoS8OdXwU7zbHuO0Wq37nvqHdQ5FTpuo,1055
1
+ orchestrator/__init__.py,sha256=SRujUPF8rKeTg1Ixeu8yyiXCPAlFG-1XYRWLEWtP0SQ,1058
2
2
  orchestrator/app.py,sha256=8GMzoHjdR0bkgRBCejiG8nIUjeo43f12I3WNNZ89pKE,11659
3
3
  orchestrator/exception_handlers.py,sha256=UsW3dw8q0QQlNLcV359bIotah8DYjMsj2Ts1LfX4ClY,1268
4
4
  orchestrator/log_config.py,sha256=1tPRX5q65e57a6a_zEii_PFK8SzWT0mnA5w2sKg4hh8,1853
@@ -8,7 +8,7 @@ orchestrator/settings.py,sha256=lrNKPtJMxZtbEZcUZ1MDGEpIDCJv_swWVoVJvwcooCY,4614
8
8
  orchestrator/targets.py,sha256=q_IMCdVUUYWcyKHqyls38fJPveJDBNfSzMKj_U2hLsk,768
9
9
  orchestrator/types.py,sha256=4vDeL5teRnugXoet3O2dMv8WwTsEyimrIfzagx9jQRo,15451
10
10
  orchestrator/version.py,sha256=b58e08lxs47wUNXv0jXFO_ykpksmytuzEXD4La4W-NQ,1366
11
- orchestrator/workflow.py,sha256=sdHAuxOsMNzHf3xum-9Lm9FE0OfCm2VcauroOTYn1fw,43051
11
+ orchestrator/workflow.py,sha256=eQEmi7IwnipDuwCmv1ipYWJbmOuxSG0_nH0-DMfUJog,43117
12
12
  orchestrator/api/__init__.py,sha256=GyHNfEFCGKQwRiN6rQmvSRH2iYX7npjMZn97n8XzmLU,571
13
13
  orchestrator/api/error_handling.py,sha256=YrPCxSa-DSa9KwqIMlXI-KGBGnbGIW5ukOPiikUH9E4,1502
14
14
  orchestrator/api/helpers.py,sha256=s0QRHYw8AvEmlkmRhuEzz9xixaZKUF3YuPzUVHkcoXk,6933
@@ -17,7 +17,7 @@ orchestrator/api/api_v1/__init__.py,sha256=GyHNfEFCGKQwRiN6rQmvSRH2iYX7npjMZn97n
17
17
  orchestrator/api/api_v1/api.py,sha256=Q_Yh9w_SBoyx06jV_kf6leGFrAMXoGjF8UikIAie_us,2858
18
18
  orchestrator/api/api_v1/endpoints/__init__.py,sha256=GyHNfEFCGKQwRiN6rQmvSRH2iYX7npjMZn97n8XzmLU,571
19
19
  orchestrator/api/api_v1/endpoints/health.py,sha256=iaxs1XX1_250_gKNsspuULCV2GEMBjbtjsmfQTOvMAI,1284
20
- orchestrator/api/api_v1/endpoints/processes.py,sha256=VPNqzogjgK9Y-70b9r-tqPSJD-6PyMj9kOrmhPC__lc,12763
20
+ orchestrator/api/api_v1/endpoints/processes.py,sha256=l85OZ-gs6YeVjFVsGhq6z_Hwkl-oY5YUagXlgzyivx8,13481
21
21
  orchestrator/api/api_v1/endpoints/product_blocks.py,sha256=kZ6ywIOsS_S2qGq7RvZ4KzjvaS1LmwbGWR37AKRvWOw,2146
22
22
  orchestrator/api/api_v1/endpoints/products.py,sha256=BfFtwu9dZXEQbtKxYj9icc73GKGvAGMR5ytyf41nQlQ,3081
23
23
  orchestrator/api/api_v1/endpoints/resource_types.py,sha256=gGyuaDyOD0TAVoeFGaGmjDGnQ8eQQArOxKrrk4MaDzA,2145
@@ -106,7 +106,7 @@ orchestrator/db/database.py,sha256=MU_w_e95ho2dVb2JDnt_KFYholx___XDkiQXbc8wCkI,1
106
106
  orchestrator/db/helpers.py,sha256=L8kEdnSSNGnUpZhdeGx2arCodakWN8vSpKdfjoLuHdY,831
107
107
  orchestrator/db/listeners.py,sha256=UBPYcH0FE3a7aZQu_D0O_JMXpXIRYXC0gjSAvlv5GZo,1142
108
108
  orchestrator/db/loaders.py,sha256=escBOUNf5bHmjIuNH37fGgNSeZLzMiJvQgQFy4r4MYY,6244
109
- orchestrator/db/models.py,sha256=LOdqw2G45TGV2Bkukj2GgXtc4nRYk1rARE0wDk_QZUE,26850
109
+ orchestrator/db/models.py,sha256=x0x4CT9LFm5XrqmY3LO9JWL7p_C7YSpbow4IRB_QLOg,26862
110
110
  orchestrator/db/filters/__init__.py,sha256=RUj6P0XxEBhYj0SN5wH5-Vf_Wt_ilZR_n9DSar5m9oM,371
111
111
  orchestrator/db/filters/filters.py,sha256=55RtpQwM2rhrk4A6CCSeSXoo-BT9GnQoNTryA8CtLEg,5020
112
112
  orchestrator/db/filters/process.py,sha256=xvGhyfo_MZ1xhLvFC6yULjcT4mJk0fKc1glJIYgsWLE,4018
@@ -198,7 +198,7 @@ orchestrator/graphql/utils/override_class.py,sha256=blwPXVHxLyXQga3KjiDzWozmMhHE
198
198
  orchestrator/graphql/utils/to_graphql_result_page.py,sha256=8ObkJP8reVf-TQOQVPKv1mNdfmSEMS1sG7s_-T7-pUU,902
199
199
  orchestrator/migrations/README,sha256=heMzebYwlGhnE8_4CWJ4LS74WoEZjBy-S-mIJRxAEKI,39
200
200
  orchestrator/migrations/alembic.ini,sha256=kMoADqhGeubU8xanILNaqm4oixLy9m4ngYtdGpZcc7I,873
201
- orchestrator/migrations/env.py,sha256=AwlgBPYbV2hr5rHNwlOPJ5rs-vRyfmzcWyxae0btpZ4,3382
201
+ orchestrator/migrations/env.py,sha256=0NrhF3vVeKMtU1kGNrc-nSfk8EnK4KbcDdUeGvWGCBM,3732
202
202
  orchestrator/migrations/helpers.py,sha256=U-b64Gp6VBq5sTDN0fqrG8mbXcpncCFVgYObW9y7ffs,43778
203
203
  orchestrator/migrations/script.py.mako,sha256=607Zrgp-Z-m9WGLt4wewN1QDOmHeifxcePUdADkSZyM,510
204
204
  orchestrator/migrations/templates/alembic.ini.j2,sha256=jA-QykVparwWSNt5XDP0Zk7epLOhK7D87Af-i2shJV4,905
@@ -206,13 +206,13 @@ orchestrator/migrations/templates/env.py.j2,sha256=RfLAQItZ56Jlzwi6LJfBo92m1-th_
206
206
  orchestrator/migrations/templates/helpers.py.j2,sha256=3MWNMICGrcQFObyBQefL-FPjoVKUgP0QIlbk4TdMZds,98
207
207
  orchestrator/migrations/versions/schema/2020-10-19_3323bcb934e7_fix_tsv_triggers.py,sha256=ufe6OFUELNpx6N2663bvdwgB4lP-v71fuMuJtx9CmJc,2698
208
208
  orchestrator/migrations/versions/schema/2020-10-19_a76b9185b334_add_generic_workflows_to_core.py,sha256=EHj87IXucruyB8KuxEWcc7JK1NIizZ5Jzmj-bzY0t1Y,1265
209
- orchestrator/migrations/versions/schema/2020-10-19_c112305b07d3_initial_schema_migration.py,sha256=gYg8JBKGu6VH7gryU-AqDPvAzx1oAAQnyGS9HMl0nSY,39307
209
+ orchestrator/migrations/versions/schema/2020-10-19_c112305b07d3_initial_schema_migration.py,sha256=-_dEwEXbl1E2HQpdcigMsSsq6H98eRcmaE8g5NR36iE,39291
210
210
  orchestrator/migrations/versions/schema/2021-04-06_3c8b9185c221_add_validate_products_task.py,sha256=rLuEl8WuQHcwmOBZdADbgCBqzJ5EZ4KWXrTVwXrRyx4,950
211
211
  orchestrator/migrations/versions/schema/2021-07-01_6896a54e9483_add_product_block_relations.py,sha256=xw01x5YTNDDxZiMUCeBPuzp0LKsKeMMR4YWF2aWI9ZI,1214
212
212
  orchestrator/migrations/versions/schema/2021-11-17_19cdd3ab86f6_fix_parse_websearch.py,sha256=FUWxAPpi32SgowU_WdZiC903BbLUA5zktBICOi4ecpQ,1603
213
213
  orchestrator/migrations/versions/schema/2022-02-16_bed6bc0b197a_rename_parent_and_child_block_relations.py,sha256=2hiV8aFwlcgRQ7EFVvGhV13j2j-p7cMLadyUfXezIF8,5106
214
214
  orchestrator/migrations/versions/schema/2023-03-06_e05bb1967eff_add_subscriptions_search_view.py,sha256=EUArauxUk_D_QWO9AKuhGIOD1a4PonH4-rVmdSx0dbs,7964
215
- orchestrator/migrations/versions/schema/2023-05-25_b1970225392d_add_subscription_metadata_workflow.py,sha256=0DhrxNXtB6cKkish5SanfpRkSx86yNL10ReKazlWuv4,1014
215
+ orchestrator/migrations/versions/schema/2023-05-25_b1970225392d_add_subscription_metadata_workflow.py,sha256=6_sH1geyl5Ier2oUmGohobpPW5OMp_jN59885DIox8g,998
216
216
  orchestrator/migrations/versions/schema/2023-06-28_a09ac125ea73_add_throttling_to_refresh_subscriptions.py,sha256=GgWBhv2QboFpES3ltoJpVM23lqp8HI9NvRuKkdF3Qzk,591
217
217
  orchestrator/migrations/versions/schema/2023-06-28_a09ac125ea73_add_throttling_to_refresh_subscriptions.sql,sha256=HYKQmWzSm7A7igjzJoOoKyGp3nQUYtThJ10OWWQo3Xs,755
218
218
  orchestrator/migrations/versions/schema/2023-07-17_165303a20fb1_customer_id_to_varchar.py,sha256=fOjZULujncwoa2QciQ4d2qcxi3iEqc_KdhdRFyfHuPc,967
@@ -223,7 +223,7 @@ orchestrator/migrations/versions/schema/2023-12-06_048219045729_add_workflow_id_
223
223
  orchestrator/migrations/versions/schema/2024-09-27_460ec6748e37_add_uuid_search_workaround.py,sha256=GzHBzOwOc6FaO1kYwoSNIhb8sKstXo8Cfxdqy3Rmeg4,972
224
224
  orchestrator/migrations/versions/schema/2024-09-27_460ec6748e37_add_uuid_search_workaround.sql,sha256=mhPnqjG5H3W8_BD7w5tYzXUQSxFOM7Rahn_MudEPTIE,5383
225
225
  orchestrator/migrations/versions/schema/2025-01-08_4c5859620539_add_version_column_to_subscription.py,sha256=xAhe74U0ZiVRo9Z8Uq7491RBbATMMUnYpTBjbG-BYL0,1690
226
- orchestrator/migrations/versions/schema/2025-02-12_bac6be6f2b4f_added_input_state_table.py,sha256=BPtx8blYEotaJv9Gnzq9Pf4ihOyzx4tfk9qwr81i8MU,1769
226
+ orchestrator/migrations/versions/schema/2025-02-12_bac6be6f2b4f_added_input_state_table.py,sha256=0vBDGltmOs_gcTTYlWBNOgItzqCXm8qqT02jZfTpL5c,1753
227
227
  orchestrator/migrations/versions/schema/2025-10-19_4fjdn13f83ga_add_validate_product_type_task.py,sha256=O0GfCISIDnyohGf3Ot_2HKedGRbMqLVox6t7Wd3PMvo,894
228
228
  orchestrator/schedules/__init__.py,sha256=JnnaglfK1qYUBKI6Dd9taV-tCZIPlAdAkHtnkJDMXxY,1066
229
229
  orchestrator/schedules/resume_workflows.py,sha256=kSotzTAXjX7p9fpSYiGOpuxuTQfv54eRFAe0YSG0DHc,832
@@ -248,7 +248,7 @@ orchestrator/services/celery.py,sha256=DHruqocnORNZUca9WDIti9GXYk9Q38BFyeJy7-N7l
248
248
  orchestrator/services/fixed_inputs.py,sha256=kyz7s2HLzyDulvcq-ZqefTw1om86COvyvTjz0_5CmgI,876
249
249
  orchestrator/services/input_state.py,sha256=HF7wl9fWdaAW8pdCCqbuYoKyNj8dY0g8Ff8vXis8z5A,2211
250
250
  orchestrator/services/process_broadcast_thread.py,sha256=D44YbjF8mRqGuznkRUV4SoRn1J0lfy_x1H508GnSVlU,4649
251
- orchestrator/services/processes.py,sha256=pucntLu1f-2ZTgSQG7l3qDX5zQGFhat4-iaq7ecglGo,27618
251
+ orchestrator/services/processes.py,sha256=NuxNHaaXc2IlLhMp0rf9-EPgsDjybDCfglQd9wBhOP0,29405
252
252
  orchestrator/services/products.py,sha256=w6b6sSA3MstmbM_YN8xWEvkb_YnuCQFph48wYU3_Lx4,1935
253
253
  orchestrator/services/resource_types.py,sha256=_QBy_JOW_X3aSTqH0CuLrq4zBJL0p7Q-UDJUcuK2_qc,884
254
254
  orchestrator/services/settings.py,sha256=u-834F4KWloXS8zi7R9mp-D3cjl-rbVjKJRU35IqhXo,2723
@@ -273,7 +273,7 @@ orchestrator/utils/json.py,sha256=7386sdqkrKYyy4sbn5NscwctH_v1hLyw5172P__rU3g,83
273
273
  orchestrator/utils/redis.py,sha256=E2vrMO3uQHb4nJENgA3WnpB0iw2C615YMuaWT-4gqoI,7027
274
274
  orchestrator/utils/redis_client.py,sha256=9rhsvedjK_CyClAjUicQyge0mVIViATqKFGZyjBY3XA,1384
275
275
  orchestrator/utils/search_query.py,sha256=ji5LHtrzohGz6b1IG41cnPdpWXzLEzz4SGWgHly_yfU,16205
276
- orchestrator/utils/state.py,sha256=DLHBnpEjhHQNeBGYV6H6geqZclToeMuWwqU26TVy220,13185
276
+ orchestrator/utils/state.py,sha256=eEmYCo9gczy0R6pIIahNyEjOnNJWI0oC5aI-1gqy5Ns,14012
277
277
  orchestrator/utils/strings.py,sha256=N0gWjmQaMjE9_99VtRvRaU8IBLTKMgBKSXcTZ9TpWAg,1077
278
278
  orchestrator/utils/validate_data_version.py,sha256=3Eioy2wE2EWKSgkyMKcEKrkCAfUIAq-eb73iRcpgppw,184
279
279
  orchestrator/websocket/__init__.py,sha256=V79jskk1z3uPIYgu0Gt6JLzuqr7NGfNeAZ-hbBqoUv4,5745
@@ -291,7 +291,7 @@ orchestrator/workflows/tasks/resume_workflows.py,sha256=R0I3jxGToiqDr5mF3YjDd6dN
291
291
  orchestrator/workflows/tasks/validate_product_type.py,sha256=5FwhRQyMNgtys5DM846EIIY0uXKvnSYy3Orf7lOg0DA,3176
292
292
  orchestrator/workflows/tasks/validate_products.py,sha256=5uXX7MXMDDP13cXRvfLDNvvCp4nG7zLQBm_IYdf8BSs,8513
293
293
  orchestrator/workflows/translations/en-GB.json,sha256=ST53HxkphFLTMjFHonykDBOZ7-P_KxksktZU3GbxLt0,846
294
- orchestrator_core-3.1.1.dist-info/licenses/LICENSE,sha256=b-aA5OZQuuBATmLKo_mln8CQrDPPhg3ghLzjPjLn4Tg,11409
295
- orchestrator_core-3.1.1.dist-info/WHEEL,sha256=_2ozNFCLWc93bK4WKHCO-eDUENDlo-dgc9cU3qokYO4,82
296
- orchestrator_core-3.1.1.dist-info/METADATA,sha256=aL3vIeJ11HtMQhH0fqPI-EvP7COQwpq7Od9r5p5Qftw,4991
297
- orchestrator_core-3.1.1.dist-info/RECORD,,
294
+ orchestrator_core-3.1.2rc3.dist-info/licenses/LICENSE,sha256=b-aA5OZQuuBATmLKo_mln8CQrDPPhg3ghLzjPjLn4Tg,11409
295
+ orchestrator_core-3.1.2rc3.dist-info/WHEEL,sha256=_2ozNFCLWc93bK4WKHCO-eDUENDlo-dgc9cU3qokYO4,82
296
+ orchestrator_core-3.1.2rc3.dist-info/METADATA,sha256=jh6W7fea4ZKjoqBM-q5LM_zvE5F1mgHEwV2_O2qO-mk,4993
297
+ orchestrator_core-3.1.2rc3.dist-info/RECORD,,