orchestrator-core 2.9.2rc1__py3-none-any.whl → 2.9.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__ = "2.9.2rc1"
16
+ __version__ = "2.9.2rc3"
17
17
 
18
18
  from orchestrator.app import OrchestratorCore
19
19
  from orchestrator.settings import app_settings
@@ -24,6 +24,7 @@ logger = structlog.get_logger(__name__)
24
24
  SUBSCRIPTION_TABLE_COLUMN_CLAUSES = default_inferred_column_clauses(SubscriptionTable) | {
25
25
  "product": inferred_filter(ProductTable.name),
26
26
  "tag": filter_exact(ProductTable.tag),
27
+ "type": filter_exact(ProductTable.product_type),
27
28
  }
28
29
 
29
30
  subscription_filter_fields = create_memoized_field_list(SUBSCRIPTION_TABLE_COLUMN_CLAUSES)
@@ -458,7 +458,7 @@ class DomainModel(BaseModel):
458
458
 
459
459
 
460
460
  def get_depends_on_product_block_type_list(
461
- product_block_types: dict[str, type["ProductBlockModel"] | tuple[type["ProductBlockModel"]]]
461
+ product_block_types: dict[str, type["ProductBlockModel"] | tuple[type["ProductBlockModel"]]],
462
462
  ) -> list[type["ProductBlockModel"]]:
463
463
  product_blocks_types_in_model = []
464
464
  for product_block_type in product_block_types.values():
@@ -0,0 +1,41 @@
1
+ """Validate Product Type.
2
+
3
+ Revision ID: 4fjdn13f83ga
4
+ Revises: 2c7e8a43d4f9
5
+ Create Date: 2025-10-13 16:21:43.956814
6
+
7
+ """
8
+
9
+ from uuid import uuid4
10
+
11
+ import sqlalchemy as sa
12
+ from alembic import op
13
+
14
+ # revision identifiers, used by Alembic.
15
+ revision = "4fjdn13f83ga"
16
+ down_revision = "4c5859620539"
17
+ branch_labels = None
18
+ depends_on = None
19
+
20
+
21
+ workflow = {
22
+ "name": "task_validate_product_type",
23
+ "target": "SYSTEM",
24
+ "description": "Validate all subscriptions of Product Type",
25
+ "workflow_id": uuid4(),
26
+ }
27
+
28
+
29
+ def upgrade() -> None:
30
+ conn = op.get_bind()
31
+ conn.execute(
32
+ sa.text(
33
+ "INSERT INTO workflows VALUES (:workflow_id, :name, :target, :description, now()) ON CONFLICT DO NOTHING"
34
+ ),
35
+ workflow,
36
+ )
37
+
38
+
39
+ def downgrade() -> None:
40
+ conn = op.get_bind()
41
+ conn.execute(sa.text("DELETE FROM workflows WHERE name = :name"), {"name": workflow["name"]})
@@ -15,14 +15,17 @@
15
15
  from threading import BoundedSemaphore
16
16
 
17
17
  import structlog
18
- from sqlalchemy import select
19
18
 
20
- from orchestrator.db import ProductTable, SubscriptionTable, db
21
19
  from orchestrator.schedules.scheduling import scheduler
22
- from orchestrator.services.processes import get_execution_context
23
- from orchestrator.services.subscriptions import TARGET_DEFAULT_USABLE_MAP, WF_USABLE_MAP
20
+ from orchestrator.services.subscriptions import (
21
+ get_subscriptions_on_product_table,
22
+ get_subscriptions_on_product_table_in_sync,
23
+ )
24
+ from orchestrator.services.workflows import (
25
+ get_system_product_workflows_for_subscription,
26
+ start_validation_workflow_for_workflows,
27
+ )
24
28
  from orchestrator.settings import app_settings
25
- from orchestrator.targets import Target
26
29
 
27
30
  logger = structlog.get_logger(__name__)
28
31
 
@@ -34,29 +37,19 @@ task_semaphore = BoundedSemaphore(value=2)
34
37
  def validate_subscriptions() -> None:
35
38
  if app_settings.VALIDATE_OUT_OF_SYNC_SUBSCRIPTIONS:
36
39
  # Automatically re-validate out-of-sync subscriptions. This is not recommended for production.
37
- select_query = select(SubscriptionTable).join(ProductTable)
40
+ subscriptions = get_subscriptions_on_product_table()
38
41
  else:
39
- select_query = select(SubscriptionTable).join(ProductTable).filter(SubscriptionTable.insync.is_(True))
40
- subscriptions = db.session.scalars(select_query)
41
- for subscription in subscriptions:
42
- validation_workflow = None
43
-
44
- for workflow in subscription.product.workflows:
45
- if workflow.target == Target.SYSTEM:
46
- validation_workflow = workflow.name
47
-
48
- if validation_workflow:
49
- default = TARGET_DEFAULT_USABLE_MAP[Target.SYSTEM]
50
- usable_when = WF_USABLE_MAP.get(validation_workflow, default)
42
+ subscriptions = get_subscriptions_on_product_table_in_sync()
51
43
 
52
- if subscription.status in usable_when:
53
- json = [{"subscription_id": str(subscription.subscription_id)}]
44
+ for subscription in subscriptions:
45
+ system_product_workflows = get_system_product_workflows_for_subscription(subscription)
54
46
 
55
- validate_func = get_execution_context()["validate"]
56
- validate_func(validation_workflow, json=json)
57
- else:
47
+ if not system_product_workflows:
58
48
  logger.warning(
59
49
  "SubscriptionTable has no validation workflow",
60
50
  subscription=subscription,
61
51
  product=subscription.product.name,
62
52
  )
53
+ break
54
+
55
+ start_validation_workflow_for_workflows(subscription=subscription, workflows=system_product_workflows)
@@ -670,3 +670,13 @@ def format_extended_domain_model(subscription: dict, filter_owner_relations: boo
670
670
  filter_instance_ids_on_subscription()
671
671
 
672
672
  return subscription
673
+
674
+
675
+ def get_subscriptions_on_product_table() -> list[SubscriptionTable]:
676
+ select_query = select(SubscriptionTable).join(ProductTable)
677
+ return list(db.session.scalars(select_query))
678
+
679
+
680
+ def get_subscriptions_on_product_table_in_sync(in_sync: bool = True) -> list[SubscriptionTable]:
681
+ select_query = select(SubscriptionTable).join(ProductTable).filter(SubscriptionTable.insync.is_(in_sync))
682
+ return list(db.session.scalars(select_query))
@@ -2,8 +2,14 @@ from collections.abc import Iterable
2
2
 
3
3
  from sqlalchemy import Select, select
4
4
 
5
- from orchestrator.db import WorkflowTable, db
5
+ from orchestrator.db import (
6
+ SubscriptionTable,
7
+ WorkflowTable,
8
+ db,
9
+ )
6
10
  from orchestrator.schemas import StepSchema, WorkflowSchema
11
+ from orchestrator.services.subscriptions import TARGET_DEFAULT_USABLE_MAP, WF_USABLE_MAP
12
+ from orchestrator.targets import Target
7
13
  from orchestrator.workflows import get_workflow
8
14
 
9
15
 
@@ -42,3 +48,43 @@ def get_workflows(
42
48
 
43
49
  def get_workflow_by_name(workflow_name: str) -> WorkflowTable | None:
44
50
  return db.session.scalar(select(WorkflowTable).where(WorkflowTable.name == workflow_name))
51
+
52
+
53
+ def get_system_product_workflows_for_subscription(
54
+ subscription: SubscriptionTable,
55
+ ) -> list:
56
+ return [workflow.name for workflow in subscription.product.workflows if workflow.target == Target.SYSTEM]
57
+
58
+
59
+ def start_validation_workflow_for_workflows(
60
+ subscription: SubscriptionTable,
61
+ workflows: list,
62
+ product_type_filter: str | None = None,
63
+ ) -> list:
64
+ """Start validation workflows for a subscription."""
65
+ result = []
66
+
67
+ for workflow_name in workflows:
68
+ default = TARGET_DEFAULT_USABLE_MAP[Target.SYSTEM]
69
+ usable_when = WF_USABLE_MAP.get(workflow_name, default)
70
+
71
+ if subscription.status in usable_when and (
72
+ product_type_filter is None or subscription.product.product_type == product_type_filter
73
+ ):
74
+ json = [{"subscription_id": str(subscription.subscription_id)}]
75
+
76
+ # against circular import
77
+ from orchestrator.services.processes import get_execution_context
78
+
79
+ validate_func = get_execution_context()["validate"]
80
+ validate_func(workflow_name, json=json)
81
+
82
+ result.append(
83
+ {
84
+ "workflow_name": workflow_name,
85
+ "subscription_id": subscription.subscription_id,
86
+ "product_type": subscription.product.product_type,
87
+ }
88
+ )
89
+
90
+ return result
@@ -86,7 +86,7 @@ def default_get_subscription_id(data: Any) -> UUID:
86
86
 
87
87
 
88
88
  def delete_subscription_from_redis(
89
- extract_fn: Callable[..., UUID] = default_get_subscription_id
89
+ extract_fn: Callable[..., UUID] = default_get_subscription_id,
90
90
  ) -> Callable[[Callable[..., Any]], Callable[..., Any]]:
91
91
  def _delete_subscription_from_redis(func: Callable[..., Any]) -> Callable[..., Any]:
92
92
  @functools.wraps(func)
@@ -110,5 +110,6 @@ LazyWorkflowInstance(".modify_note", "modify_note")
110
110
  LazyWorkflowInstance(".tasks.cleanup_tasks_log", "task_clean_up_tasks")
111
111
  LazyWorkflowInstance(".tasks.resume_workflows", "task_resume_workflows")
112
112
  LazyWorkflowInstance(".tasks.validate_products", "task_validate_products")
113
+ LazyWorkflowInstance(".tasks.validate_product_type", "task_validate_product_type")
113
114
 
114
115
  __doc__ = make_workflow_index_doc(ALL_WORKFLOWS)
@@ -0,0 +1,92 @@
1
+ # Copyright 2019-2024 SURF.
2
+ # Licensed under the Apache License, Version 2.0 (the "License");
3
+ # you may not use this file except in compliance with the License.
4
+ # You may obtain a copy of the License at
5
+ #
6
+ # http://www.apache.org/licenses/LICENSE-2.0
7
+ #
8
+ # Unless required by applicable law or agreed to in writing, software
9
+ # distributed under the License is distributed on an "AS IS" BASIS,
10
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11
+ # See the License for the specific language governing permissions and
12
+ # limitations under the License.
13
+ from functools import cache
14
+ from typing import Any
15
+
16
+ import structlog
17
+
18
+ from orchestrator.db import ProductTable
19
+ from orchestrator.forms import FormPage
20
+ from orchestrator.forms.validators import Choice
21
+ from orchestrator.services.subscriptions import (
22
+ get_subscriptions_on_product_table_in_sync,
23
+ )
24
+ from orchestrator.services.workflows import (
25
+ get_system_product_workflows_for_subscription,
26
+ start_validation_workflow_for_workflows,
27
+ )
28
+ from orchestrator.targets import Target
29
+ from orchestrator.types import FormGenerator, State
30
+ from orchestrator.workflow import StepList, done, init, step, workflow
31
+
32
+ logger = structlog.get_logger(__name__)
33
+
34
+
35
+ def create_select_product_type_form() -> type[FormPage]:
36
+ """Get and create the choices form for the product type."""
37
+
38
+ @cache
39
+ def get_product_type_choices() -> dict[Any, Any]:
40
+ return {product.product_type: product.product_type for product in ProductTable.query.all()}
41
+
42
+ ProductTypeChoices = Choice.__call__("Product Type", get_product_type_choices())
43
+
44
+ class SelectProductTypeForm(FormPage):
45
+ product_type: ProductTypeChoices # type: ignore
46
+
47
+ return SelectProductTypeForm
48
+
49
+
50
+ def initial_input_form_generator() -> FormGenerator:
51
+ """Generate the form."""
52
+
53
+ init_input = yield create_select_product_type_form()
54
+ user_input_data = init_input.model_dump()
55
+
56
+ return user_input_data
57
+
58
+
59
+ @step("Validate Product Type")
60
+ def validate_product_type(product_type: str) -> State:
61
+ result = []
62
+ subscriptions = get_subscriptions_on_product_table_in_sync()
63
+
64
+ for subscription in subscriptions:
65
+ system_product_workflows = get_system_product_workflows_for_subscription(
66
+ subscription=subscription,
67
+ )
68
+
69
+ if not system_product_workflows:
70
+ logger.warning(
71
+ "SubscriptionTable has no validation workflow",
72
+ subscription=subscription,
73
+ product=subscription.product.name,
74
+ )
75
+ continue
76
+
77
+ validation_result = start_validation_workflow_for_workflows(
78
+ subscription=subscription,
79
+ workflows=system_product_workflows,
80
+ product_type_filter=product_type,
81
+ )
82
+ if len(validation_result) > 0:
83
+ result.append({"total_workflows_validated": len(validation_result), "workflows": validation_result})
84
+
85
+ return {"result": result}
86
+
87
+
88
+ @workflow(
89
+ "Validate all subscriptions of Product Type", target=Target.SYSTEM, initial_input_form=initial_input_form_generator
90
+ )
91
+ def task_validate_product_type() -> StepList:
92
+ return init >> validate_product_type >> done
@@ -5,7 +5,8 @@
5
5
  "note_info": "Notes, reminders and feedback about this description.",
6
6
  "subscription_id": "Subscription",
7
7
  "version": "Version",
8
- "subscription_id_info": "The subscription for this action"
8
+ "subscription_id_info": "The subscription for this action",
9
+ "product_type": "Product Type"
9
10
  }
10
11
  },
11
12
  "workflow": {
@@ -13,6 +14,7 @@
13
14
  "task_clean_up_tasks": "Clean up old tasks",
14
15
  "task_resume_workflows": "Resume all workflows that are stuck on tasks with the status 'waiting'",
15
16
  "task_validate_products": "Validate Products and Subscriptions",
17
+ "task_validate_product_type": "Validate all subscriptions of Product Type",
16
18
  "reset_subscription_description": "Reset description of a subscription to default"
17
19
  }
18
20
  }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: orchestrator-core
3
- Version: 2.9.2rc1
3
+ Version: 2.9.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
@@ -56,7 +56,7 @@ Requires-Dist: nwa-stdlib~=1.9.0
56
56
  Requires-Dist: oauth2-lib~=2.4.0
57
57
  Requires-Dist: tabulate==0.9.0
58
58
  Requires-Dist: strawberry-graphql>=0.246.2
59
- Requires-Dist: pydantic-forms~=1.1.3
59
+ Requires-Dist: pydantic-forms~=1.2.1
60
60
  Requires-Dist: celery~=5.4.0 ; extra == "celery"
61
61
  Requires-Dist: toml ; extra == "dev"
62
62
  Requires-Dist: bumpversion ; extra == "dev"
@@ -1,4 +1,4 @@
1
- orchestrator/__init__.py,sha256=uaK-K8eDckfC2-j5UCP7FLkLp1C-yjYFRIzbLwrrUak,1058
1
+ orchestrator/__init__.py,sha256=ZEfVsV-TQSD6cNrXVHcgemFAbqGTVKsyAnxfA9sraH8,1058
2
2
  orchestrator/app.py,sha256=_2e3JMYgH_egOScokFVpFuTlJWGGwH0KYgZajDdm--0,11563
3
3
  orchestrator/exception_handlers.py,sha256=UsW3dw8q0QQlNLcV359bIotah8DYjMsj2Ts1LfX4ClY,1268
4
4
  orchestrator/log_config.py,sha256=1tPRX5q65e57a6a_zEii_PFK8SzWT0mnA5w2sKg4hh8,1853
@@ -109,7 +109,7 @@ orchestrator/db/filters/process.py,sha256=xvGhyfo_MZ1xhLvFC6yULjcT4mJk0fKc1glJIY
109
109
  orchestrator/db/filters/product.py,sha256=ZsoZZ8ExpmP22T_8Zg1ZVxs3DbC2_n4-dBgIlxrw_Q0,899
110
110
  orchestrator/db/filters/product_block.py,sha256=CYym-QIkkgJ2rEsUPVoe-lcEphHb0xFBbA2cOCF2eLU,1089
111
111
  orchestrator/db/filters/resource_type.py,sha256=7aH4_n8vPpsySFnnN8SefN8h964glmEiw_SYip1lc8I,889
112
- orchestrator/db/filters/subscription.py,sha256=6IA_X-nXFU_VRsEQlRdg_aVq_7vJoVfZ7V-FpsPFIZ8,1466
112
+ orchestrator/db/filters/subscription.py,sha256=IV7ur7yyKFNUQRx0gZPelcMLHjuUPU0Rx4oZ6Shbn6A,1519
113
113
  orchestrator/db/filters/workflow.py,sha256=osyyEmOFuev6q5lizHeUvgxf1Nji3fZtlbf2_lzSNao,1276
114
114
  orchestrator/db/filters/search_filters/__init__.py,sha256=a7yfEAA-qpD_PHZH5LeqSjrLeGAvQrDsJp7mzVwDMwo,562
115
115
  orchestrator/db/filters/search_filters/inferred_filter.py,sha256=B3WuA6yi3AFhkgbr8yK0UnqiZNUZ1h1aNFQCtNqaP7I,5591
@@ -133,7 +133,7 @@ orchestrator/distlock/managers/__init__.py,sha256=ImIkNsrXcyE7-NgRWqEhUXUuUzda9K
133
133
  orchestrator/distlock/managers/memory_distlock_manager.py,sha256=HWQafcVKBF-Cka_wukZZ1GM69AWPVOpJPje3quIebQ8,3114
134
134
  orchestrator/distlock/managers/redis_distlock_manager.py,sha256=Lk0Krw7dQD58uleAz3Eancc4La-xSCFHxB8ymg3qWf0,3271
135
135
  orchestrator/domain/__init__.py,sha256=Rnt9XXHasAgieQiLT0JhUFRrysa9EIubvzcd5kk3Gvc,894
136
- orchestrator/domain/base.py,sha256=8iiz1IP6CSrr5pz_0oqRNj5MoHY4PR9E30hx8Zrlrq4,61928
136
+ orchestrator/domain/base.py,sha256=2yehcuXSkq3H2wl8y19qeY98BQX_aL2i5QxxAU896JI,61929
137
137
  orchestrator/domain/customer_description.py,sha256=v7o6TTN4oc6bWHZU-jCT-fUYvkeYahbpXOwlKXofuI8,3360
138
138
  orchestrator/domain/helpers.py,sha256=2j2j_7J8qvniHxxpdoEQsoVpC-llkn0tbww2eCA0K1A,989
139
139
  orchestrator/domain/lifecycle.py,sha256=ROYJ5t6JFy5PwE9nmApS54NIEw0dwk-2iZC-OzW18-U,2882
@@ -215,12 +215,13 @@ orchestrator/migrations/versions/schema/2023-12-06_048219045729_add_workflow_id_
215
215
  orchestrator/migrations/versions/schema/2024-09-27_460ec6748e37_add_uuid_search_workaround.py,sha256=GzHBzOwOc6FaO1kYwoSNIhb8sKstXo8Cfxdqy3Rmeg4,972
216
216
  orchestrator/migrations/versions/schema/2024-09-27_460ec6748e37_add_uuid_search_workaround.sql,sha256=mhPnqjG5H3W8_BD7w5tYzXUQSxFOM7Rahn_MudEPTIE,5383
217
217
  orchestrator/migrations/versions/schema/2025-01-08_4c5859620539_add_version_column_to_subscription.py,sha256=xAhe74U0ZiVRo9Z8Uq7491RBbATMMUnYpTBjbG-BYL0,1690
218
+ orchestrator/migrations/versions/schema/2025-10-19_4fjdn13f83ga_add_validate_product_type_task.py,sha256=O0GfCISIDnyohGf3Ot_2HKedGRbMqLVox6t7Wd3PMvo,894
218
219
  orchestrator/schedules/__init__.py,sha256=JnnaglfK1qYUBKI6Dd9taV-tCZIPlAdAkHtnkJDMXxY,1066
219
220
  orchestrator/schedules/resume_workflows.py,sha256=kSotzTAXjX7p9fpSYiGOpuxuTQfv54eRFAe0YSG0DHc,832
220
221
  orchestrator/schedules/scheduling.py,sha256=ehtwgpbvMOk1jhn-hHgVzg_9wLJkI6l3mRY3DcO9ZVY,1526
221
222
  orchestrator/schedules/task_vacuum.py,sha256=eovnuKimU8SFRw1IF62MsAVFSdgeeV1u57kapUbz8As,821
222
223
  orchestrator/schedules/validate_products.py,sha256=YMr7ASSqdXM6pd6oZu0kr8mfmH8If16MzprrsHdN_ZU,1234
223
- orchestrator/schedules/validate_subscriptions.py,sha256=MI6Ci26t1fvcs5yC2Bwo2xZK2ycF9-TMMw8R0CRLWvI,2501
224
+ orchestrator/schedules/validate_subscriptions.py,sha256=YYcU2iGf8Ga_s577kgpKdhQV4p7wCEHGYvUf8FCvBvQ,2022
224
225
  orchestrator/schemas/__init__.py,sha256=YDyZ0YBvzB4ML9oDBCBPGnBvf680zFFgUzg7X0tYBRY,2326
225
226
  orchestrator/schemas/base.py,sha256=Vc444LetsINLRhG2SxW9Bq01hOzChPOhQWCImQTr-As,930
226
227
  orchestrator/schemas/engine_settings.py,sha256=BOyFNOn7AqHVdUxXyqmPk5aVdFY5A0cCOZ4bAwxQsgo,1286
@@ -242,10 +243,10 @@ orchestrator/services/products.py,sha256=5lKxnfDw80YkF3jOvV1v8c8FtR6allVk3MwpRSD
242
243
  orchestrator/services/resource_types.py,sha256=_QBy_JOW_X3aSTqH0CuLrq4zBJL0p7Q-UDJUcuK2_qc,884
243
244
  orchestrator/services/settings.py,sha256=u-834F4KWloXS8zi7R9mp-D3cjl-rbVjKJRU35IqhXo,2723
244
245
  orchestrator/services/subscription_relations.py,sha256=9C126TUfFvyBe7y4x007kH_dvxJ9pZ1zSnaWeH6HC5k,12261
245
- orchestrator/services/subscriptions.py,sha256=5SfaruUje2WuAvp2t7KRa-UHEqIU6jvcd_hFWSdxiwA,25733
246
+ orchestrator/services/subscriptions.py,sha256=AEuh0p2pmVLDXWE-ylJMD32NQUuqw1_jbaPAYvx_wvA,26177
246
247
  orchestrator/services/tasks.py,sha256=f3045Hn9uWIXcRvIPN6qdznH_0u-rsIGM9hHalc_BvE,6286
247
248
  orchestrator/services/translations.py,sha256=GyP8soUFGej8AS8uulBsk10CCK6Kwfjv9AHMFm3ElQY,1713
248
- orchestrator/services/workflows.py,sha256=mxXQk2ETNF0LhhsUBU5OumfjVPOjAaO-JsZmWmEB4NQ,1638
249
+ orchestrator/services/workflows.py,sha256=DStBiQQdPV3zEg1EgPDlk85T6kkBc9AKbiEpxrQG6dI,3170
249
250
  orchestrator/utils/__init__.py,sha256=GyHNfEFCGKQwRiN6rQmvSRH2iYX7npjMZn97n8XzmLU,571
250
251
  orchestrator/utils/crypt.py,sha256=18eNamYWMllPkxyRtWIde3FDr3rSF74R5SAL6WsCj9Y,5584
251
252
  orchestrator/utils/datetime.py,sha256=a1WQ_yvu7MA0TiaRpC5avwbOSFdrj4eMrV4a7I2sD5Q,1477
@@ -259,7 +260,7 @@ orchestrator/utils/get_subscription_dict.py,sha256=fkgDM54hn5YGUP9_2MOcJApJK1Z6c
259
260
  orchestrator/utils/get_updated_properties.py,sha256=egVZ0R5LNJ4e51Z8SXlU8cmb4tXxG-xb1d7OKwh-7xI,1322
260
261
  orchestrator/utils/helpers.py,sha256=NjUF3IvWdnLulliP8-JQvGGGpHrh0vs0Vm092ynw-ss,3212
261
262
  orchestrator/utils/json.py,sha256=7386sdqkrKYyy4sbn5NscwctH_v1hLyw5172P__rU3g,8341
262
- orchestrator/utils/redis.py,sha256=WZiTjjQIO5TZIRllm-a6cQbndKE7hAxxj6mus_gToOs,7221
263
+ orchestrator/utils/redis.py,sha256=fvALD_Yt4lZuIfgCLGJwwQSElgKOLHrxH_RdhSXkeZw,7222
263
264
  orchestrator/utils/search_query.py,sha256=ncJlynwtW-qwL0RcNq4DuAUx9KUMI6llwGAEwLO2QCA,17097
264
265
  orchestrator/utils/state.py,sha256=gPYHOWDxPvoYZ83WwKPCpeBAsNWOTlkwZz5kAZcM9rw,13011
265
266
  orchestrator/utils/strings.py,sha256=N0gWjmQaMjE9_99VtRvRaU8IBLTKMgBKSXcTZ9TpWAg,1077
@@ -268,7 +269,7 @@ orchestrator/websocket/__init__.py,sha256=V79jskk1z3uPIYgu0Gt6JLzuqr7NGfNeAZ-hbB
268
269
  orchestrator/websocket/websocket_manager.py,sha256=Vw5GW67rP_RYoPUhfPp9Fi8_M9E9SoHOHmCQVibkSWc,2755
269
270
  orchestrator/websocket/managers/broadcast_websocket_manager.py,sha256=fwoSgTjkHJ2GmsLTU9dqQpAA9i8b1McPu7gLNzxtfG4,5401
270
271
  orchestrator/websocket/managers/memory_websocket_manager.py,sha256=lF5EEx1iFMCGEkTbItTDr88NENMSaSeG1QrJ7teoPkY,3324
271
- orchestrator/workflows/__init__.py,sha256=TOZ7Q5_DolCsW6dl5RRndbNFkBHLeGk_R5c4W7pIK8k,4048
272
+ orchestrator/workflows/__init__.py,sha256=NzIGGI-8SNAwCk2YqH6sHhEWbgAY457ntDwjO15N8v4,4131
272
273
  orchestrator/workflows/modify_note.py,sha256=OkouKVZDinjWSN3J3_0gbvOMScvcKlWvPCkban45HxE,2438
273
274
  orchestrator/workflows/removed_workflow.py,sha256=V0Da5TEdfLdZZKD38ig-MTp3_IuE7VGqzHHzvPYQmLI,909
274
275
  orchestrator/workflows/steps.py,sha256=8dnB4HlqBWZ4JlP1eQVnHdinzoM0ZlgFL0KYn_3k8x4,9762
@@ -276,9 +277,10 @@ orchestrator/workflows/utils.py,sha256=inWbR-44B0jj8YZMFBxndpcsfk5IC0MnlCnGB2dy5
276
277
  orchestrator/workflows/tasks/__init__.py,sha256=GyHNfEFCGKQwRiN6rQmvSRH2iYX7npjMZn97n8XzmLU,571
277
278
  orchestrator/workflows/tasks/cleanup_tasks_log.py,sha256=JNx2lCIxdhTPD33EgwQUsQjoLeyKH2RKZR_e5eh80Ls,1614
278
279
  orchestrator/workflows/tasks/resume_workflows.py,sha256=wZGNHHQYL7wociSTmoNdDdh5CJkVOkvu3kCUg9uY_88,2349
280
+ orchestrator/workflows/tasks/validate_product_type.py,sha256=kVuN94hGWcmBNphgpAlGTSiyO2dEhFwgIq87SYjArns,3174
279
281
  orchestrator/workflows/tasks/validate_products.py,sha256=j_aOyxcH8DymlGupSS6XRwQdWx2Ab-c8f8iUvAXBTes,8511
280
- orchestrator/workflows/translations/en-GB.json,sha256=e6uKt70KLSCmCSWQF9HpmVTLQM4YYO-9xFaMYcc58Ic,718
281
- orchestrator_core-2.9.2rc1.dist-info/LICENSE,sha256=b-aA5OZQuuBATmLKo_mln8CQrDPPhg3ghLzjPjLn4Tg,11409
282
- orchestrator_core-2.9.2rc1.dist-info/WHEEL,sha256=CpUCUxeHQbRN5UGRQHYRJorO5Af-Qy_fHMctcQ8DSGI,82
283
- orchestrator_core-2.9.2rc1.dist-info/METADATA,sha256=zUOL3E-Vk0quv01_5iO6Z4AAEgmeXIwFLvadLsXK_kY,4924
284
- orchestrator_core-2.9.2rc1.dist-info/RECORD,,
282
+ orchestrator/workflows/translations/en-GB.json,sha256=ST53HxkphFLTMjFHonykDBOZ7-P_KxksktZU3GbxLt0,846
283
+ orchestrator_core-2.9.2rc3.dist-info/LICENSE,sha256=b-aA5OZQuuBATmLKo_mln8CQrDPPhg3ghLzjPjLn4Tg,11409
284
+ orchestrator_core-2.9.2rc3.dist-info/WHEEL,sha256=CpUCUxeHQbRN5UGRQHYRJorO5Af-Qy_fHMctcQ8DSGI,82
285
+ orchestrator_core-2.9.2rc3.dist-info/METADATA,sha256=3rVMT6j1-fRT6J3eL_MCkSerRs1RURkFTwCs1ejjA74,4924
286
+ orchestrator_core-2.9.2rc3.dist-info/RECORD,,