orchestrator-core 3.2.3__py3-none-any.whl → 4.0.0rc1__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 +1 -1
- orchestrator/api/api_v1/endpoints/subscription_customer_descriptions.py +0 -2
- orchestrator/db/models.py +1 -1
- orchestrator/domain/base.py +4 -24
- orchestrator/domain/customer_description.py +0 -4
- orchestrator/graphql/mutations/customer_description.py +1 -1
- orchestrator/migrations/versions/schema/2025-02-20_68d14db1b8da_make_workflow_description_mandatory.py +33 -0
- orchestrator/services/processes.py +1 -0
- orchestrator/services/subscriptions.py +6 -22
- orchestrator/settings.py +0 -4
- orchestrator/utils/get_subscription_dict.py +0 -4
- orchestrator/utils/redis.py +1 -67
- orchestrator/workflows/modify_note.py +3 -11
- orchestrator/workflows/steps.py +2 -86
- orchestrator/workflows/utils.py +2 -22
- {orchestrator_core-3.2.3.dist-info → orchestrator_core-4.0.0rc1.dist-info}/METADATA +6 -6
- {orchestrator_core-3.2.3.dist-info → orchestrator_core-4.0.0rc1.dist-info}/RECORD +19 -18
- {orchestrator_core-3.2.3.dist-info → orchestrator_core-4.0.0rc1.dist-info}/WHEEL +0 -0
- {orchestrator_core-3.2.3.dist-info → orchestrator_core-4.0.0rc1.dist-info}/licenses/LICENSE +0 -0
orchestrator/__init__.py
CHANGED
|
@@ -28,7 +28,6 @@ from orchestrator.domain.customer_description import (
|
|
|
28
28
|
from orchestrator.schemas import SubscriptionDescriptionBaseSchema, SubscriptionDescriptionSchema
|
|
29
29
|
from orchestrator.schemas.subscription_descriptions import UpdateSubscriptionDescriptionSchema
|
|
30
30
|
from orchestrator.utils.errors import StaleDataError
|
|
31
|
-
from orchestrator.utils.redis import delete_from_redis
|
|
32
31
|
|
|
33
32
|
router = APIRouter()
|
|
34
33
|
|
|
@@ -55,7 +54,6 @@ def delete_subscription_customer_descriptions(_id: UUID) -> None:
|
|
|
55
54
|
description = db.session.get(SubscriptionCustomerDescriptionTable, _id)
|
|
56
55
|
if description:
|
|
57
56
|
delete(SubscriptionCustomerDescriptionTable, _id)
|
|
58
|
-
delete_from_redis(description.subscription_id)
|
|
59
57
|
|
|
60
58
|
|
|
61
59
|
@router.get("/{_id}", response_model=SubscriptionDescriptionSchema)
|
orchestrator/db/models.py
CHANGED
|
@@ -400,7 +400,7 @@ class WorkflowTable(BaseModel):
|
|
|
400
400
|
workflow_id = mapped_column(UUIDType, server_default=text("uuid_generate_v4()"), primary_key=True)
|
|
401
401
|
name = mapped_column(String(), nullable=False, unique=True)
|
|
402
402
|
target = mapped_column(String(), nullable=False)
|
|
403
|
-
description = mapped_column(Text(), nullable=
|
|
403
|
+
description = mapped_column(Text(), nullable=False)
|
|
404
404
|
created_at = mapped_column(UtcTimestamp, nullable=False, server_default=text("current_timestamp()"))
|
|
405
405
|
deleted_at = mapped_column(UtcTimestamp, deferred=True)
|
|
406
406
|
|
orchestrator/domain/base.py
CHANGED
|
@@ -1294,27 +1294,13 @@ class SubscriptionModel(DomainModel):
|
|
|
1294
1294
|
# Some common functions shared by from_other_product and from_subscription
|
|
1295
1295
|
@classmethod
|
|
1296
1296
|
def _get_subscription(cls: type[S], subscription_id: UUID | UUIDstr) -> SubscriptionTable | None:
|
|
1297
|
-
from orchestrator.settings import app_settings
|
|
1298
1297
|
|
|
1299
1298
|
if not isinstance(subscription_id, UUID | UUIDstr):
|
|
1300
1299
|
raise TypeError(f"subscription_id is of type {type(subscription_id)} instead of UUID | UUIDstr")
|
|
1301
1300
|
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
joinedload(SubscriptionTable.product).selectinload(ProductTable.fixed_inputs),
|
|
1306
|
-
]
|
|
1307
|
-
|
|
1308
|
-
else:
|
|
1309
|
-
loaders = [
|
|
1310
|
-
selectinload(SubscriptionTable.instances)
|
|
1311
|
-
.joinedload(SubscriptionInstanceTable.product_block)
|
|
1312
|
-
.selectinload(ProductBlockTable.resource_types),
|
|
1313
|
-
selectinload(SubscriptionTable.instances).selectinload(
|
|
1314
|
-
SubscriptionInstanceTable.in_use_by_block_relations
|
|
1315
|
-
),
|
|
1316
|
-
selectinload(SubscriptionTable.instances).selectinload(SubscriptionInstanceTable.values),
|
|
1317
|
-
]
|
|
1301
|
+
loaders = [
|
|
1302
|
+
joinedload(SubscriptionTable.product).selectinload(ProductTable.fixed_inputs),
|
|
1303
|
+
]
|
|
1318
1304
|
|
|
1319
1305
|
return db.session.get(SubscriptionTable, subscription_id, options=loaders)
|
|
1320
1306
|
|
|
@@ -1394,7 +1380,6 @@ class SubscriptionModel(DomainModel):
|
|
|
1394
1380
|
def from_subscription(cls: type[S], subscription_id: UUID | UUIDstr) -> S:
|
|
1395
1381
|
"""Use a subscription_id to return required fields of an existing subscription."""
|
|
1396
1382
|
from orchestrator.domain.context_cache import get_from_cache, store_in_cache
|
|
1397
|
-
from orchestrator.settings import app_settings
|
|
1398
1383
|
|
|
1399
1384
|
if cached_model := get_from_cache(subscription_id):
|
|
1400
1385
|
return cast(S, cached_model)
|
|
@@ -1421,12 +1406,7 @@ class SubscriptionModel(DomainModel):
|
|
|
1421
1406
|
|
|
1422
1407
|
fixed_inputs = {fi.name: fi.value for fi in subscription.product.fixed_inputs}
|
|
1423
1408
|
|
|
1424
|
-
instances
|
|
1425
|
-
if app_settings.ENABLE_SUBSCRIPTION_MODEL_OPTIMIZATIONS:
|
|
1426
|
-
# TODO #900 remove toggle and make this path the default
|
|
1427
|
-
instances = cls._load_root_instances(subscription_id)
|
|
1428
|
-
else:
|
|
1429
|
-
instances = cls._load_instances(subscription.instances, status, match_domain_attr=False)
|
|
1409
|
+
instances = cls._load_root_instances(subscription_id)
|
|
1430
1410
|
|
|
1431
1411
|
try:
|
|
1432
1412
|
model = cls(
|
|
@@ -21,7 +21,6 @@ from sqlalchemy import select
|
|
|
21
21
|
from orchestrator.api.models import delete
|
|
22
22
|
from orchestrator.db import SubscriptionCustomerDescriptionTable, db
|
|
23
23
|
from orchestrator.utils.errors import StaleDataError
|
|
24
|
-
from orchestrator.utils.redis import delete_subscription_from_redis
|
|
25
24
|
from orchestrator.utils.validate_data_version import validate_data_version
|
|
26
25
|
from orchestrator.websocket import invalidate_subscription_cache
|
|
27
26
|
|
|
@@ -38,7 +37,6 @@ def get_customer_description_by_customer_subscription(
|
|
|
38
37
|
return db.session.scalars(stmt).one_or_none()
|
|
39
38
|
|
|
40
39
|
|
|
41
|
-
@delete_subscription_from_redis()
|
|
42
40
|
async def create_subscription_customer_description(
|
|
43
41
|
customer_id: str, subscription_id: UUID, description: str
|
|
44
42
|
) -> SubscriptionCustomerDescriptionTable:
|
|
@@ -53,7 +51,6 @@ async def create_subscription_customer_description(
|
|
|
53
51
|
return customer_description
|
|
54
52
|
|
|
55
53
|
|
|
56
|
-
@delete_subscription_from_redis()
|
|
57
54
|
async def update_subscription_customer_description(
|
|
58
55
|
customer_description: SubscriptionCustomerDescriptionTable,
|
|
59
56
|
description: str,
|
|
@@ -70,7 +67,6 @@ async def update_subscription_customer_description(
|
|
|
70
67
|
return customer_description
|
|
71
68
|
|
|
72
69
|
|
|
73
|
-
@delete_subscription_from_redis()
|
|
74
70
|
async def delete_subscription_customer_description_by_customer_subscription(
|
|
75
71
|
customer_id: str, subscription_id: UUID
|
|
76
72
|
) -> SubscriptionCustomerDescriptionTable | None:
|
|
@@ -60,7 +60,7 @@ async def resolve_remove_customer_description(
|
|
|
60
60
|
)
|
|
61
61
|
if not description:
|
|
62
62
|
return NotFoundError(message="Customer description not found")
|
|
63
|
-
return CustomerDescription.from_pydantic(description)
|
|
63
|
+
return CustomerDescription.from_pydantic(description) # type: ignore
|
|
64
64
|
|
|
65
65
|
|
|
66
66
|
@strawberry.type(description="Customer subscription description mutations")
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"""Make workflow description mandatory.
|
|
2
|
+
|
|
3
|
+
Revision ID: 68d14db1b8da
|
|
4
|
+
Revises: bac6be6f2b4f
|
|
5
|
+
Create Date: 2025-02-20 16:39:34.889953
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import sqlalchemy as sa
|
|
10
|
+
from alembic import op
|
|
11
|
+
from structlog import get_logger
|
|
12
|
+
|
|
13
|
+
logger = get_logger(__name__)
|
|
14
|
+
|
|
15
|
+
# revision identifiers, used by Alembic.
|
|
16
|
+
revision = "68d14db1b8da"
|
|
17
|
+
down_revision = "bac6be6f2b4f"
|
|
18
|
+
branch_labels = None
|
|
19
|
+
depends_on = None
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def upgrade() -> None:
|
|
23
|
+
try:
|
|
24
|
+
op.alter_column("workflows", "description", existing_type=sa.TEXT(), nullable=False)
|
|
25
|
+
except sa.exc.IntegrityError:
|
|
26
|
+
logger.error(
|
|
27
|
+
"Unable to execute migrations due to missing descriptions in workflow table, please create a migration to backfill this column."
|
|
28
|
+
)
|
|
29
|
+
raise
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def downgrade() -> None:
|
|
33
|
+
op.alter_column("workflows", "description", existing_type=sa.TEXT(), nullable=True)
|
|
@@ -605,7 +605,6 @@ def build_domain_model(subscription_model: SubscriptionModel) -> dict:
|
|
|
605
605
|
|
|
606
606
|
def build_extended_domain_model(subscription_model: SubscriptionModel) -> dict:
|
|
607
607
|
"""Create a subscription dict from the SubscriptionModel with additional keys."""
|
|
608
|
-
from orchestrator.settings import app_settings
|
|
609
608
|
|
|
610
609
|
stmt = select(SubscriptionCustomerDescriptionTable).where(
|
|
611
610
|
SubscriptionCustomerDescriptionTable.subscription_id == subscription_model.subscription_id
|
|
@@ -615,27 +614,12 @@ def build_extended_domain_model(subscription_model: SubscriptionModel) -> dict:
|
|
|
615
614
|
with cache_subscription_models():
|
|
616
615
|
subscription = subscription_model.model_dump()
|
|
617
616
|
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
update_in(subscription, f"{path_to_block}.in_use_by_ids", in_use_by_ids)
|
|
625
|
-
update_in(subscription, f"{path_to_block}.in_use_by_relations", in_use_by_relations)
|
|
626
|
-
|
|
627
|
-
if app_settings.ENABLE_SUBSCRIPTION_MODEL_OPTIMIZATIONS:
|
|
628
|
-
# TODO #900 remove toggle and make this path the default
|
|
629
|
-
# query all subscription instances and inject the in_use_by_ids/in_use_by_relations into the subscription dict.
|
|
630
|
-
instance_to_in_use_by = {
|
|
631
|
-
instance.subscription_instance_id: instance.in_use_by
|
|
632
|
-
for instance in eagerload_all_subscription_instances_only_inuseby(subscription_model.subscription_id)
|
|
633
|
-
}
|
|
634
|
-
inject_in_use_by_ids_v2(subscription, instance_to_in_use_by)
|
|
635
|
-
else:
|
|
636
|
-
# find all product blocks, check if they have in_use_by and inject the in_use_by_ids into the subscription dict.
|
|
637
|
-
for path in product_block_paths(subscription):
|
|
638
|
-
inject_in_use_by_ids(path)
|
|
617
|
+
# query all subscription instances and inject the in_use_by_ids/in_use_by_relations into the subscription dict.
|
|
618
|
+
instance_to_in_use_by = {
|
|
619
|
+
instance.subscription_instance_id: instance.in_use_by
|
|
620
|
+
for instance in eagerload_all_subscription_instances_only_inuseby(subscription_model.subscription_id)
|
|
621
|
+
}
|
|
622
|
+
inject_in_use_by_ids_v2(subscription, instance_to_in_use_by)
|
|
639
623
|
|
|
640
624
|
subscription["customer_descriptions"] = customer_descriptions
|
|
641
625
|
|
orchestrator/settings.py
CHANGED
|
@@ -55,7 +55,6 @@ class AppSettings(BaseSettings):
|
|
|
55
55
|
MAIL_PORT: int = 25
|
|
56
56
|
MAIL_STARTTLS: bool = False
|
|
57
57
|
CACHE_URI: RedisDsn = "redis://localhost:6379/0" # type: ignore
|
|
58
|
-
CACHE_DOMAIN_MODELS: bool = False
|
|
59
58
|
CACHE_HMAC_SECRET: str | None = None # HMAC signing key, used when pickling results in the cache
|
|
60
59
|
REDIS_RETRY_COUNT: NonNegativeInt = Field(
|
|
61
60
|
2, description="Number of retries for redis connection errors/timeouts, 0 to disable"
|
|
@@ -87,9 +86,6 @@ class AppSettings(BaseSettings):
|
|
|
87
86
|
ENABLE_GRAPHQL_STATS_EXTENSION: bool = False
|
|
88
87
|
VALIDATE_OUT_OF_SYNC_SUBSCRIPTIONS: bool = False
|
|
89
88
|
FILTER_BY_MODE: Literal["partial", "exact"] = "exact"
|
|
90
|
-
ENABLE_SUBSCRIPTION_MODEL_OPTIMIZATIONS: bool = (
|
|
91
|
-
True # True=ignore cache + optimized DB queries; False=use cache + unoptimized DB queries. Remove in #900
|
|
92
|
-
)
|
|
93
89
|
|
|
94
90
|
|
|
95
91
|
app_settings = AppSettings()
|
|
@@ -2,15 +2,11 @@ from uuid import UUID
|
|
|
2
2
|
|
|
3
3
|
from orchestrator.domain.base import SubscriptionModel
|
|
4
4
|
from orchestrator.services.subscriptions import _generate_etag, build_domain_model, build_extended_domain_model
|
|
5
|
-
from orchestrator.utils.redis import from_redis
|
|
6
5
|
|
|
7
6
|
|
|
8
7
|
async def get_subscription_dict(subscription_id: UUID, inject_inuseby: bool = True) -> tuple[dict, str]:
|
|
9
8
|
"""Helper function to get subscription dict by uuid from db or cache."""
|
|
10
9
|
|
|
11
|
-
if cached_model := from_redis(subscription_id):
|
|
12
|
-
return cached_model # type: ignore
|
|
13
|
-
|
|
14
10
|
subscription_model = SubscriptionModel.from_subscription(subscription_id)
|
|
15
11
|
|
|
16
12
|
if not inject_inuseby:
|
orchestrator/utils/redis.py
CHANGED
|
@@ -10,11 +10,9 @@
|
|
|
10
10
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
11
|
# See the License for the specific language governing permissions and
|
|
12
12
|
# limitations under the License.
|
|
13
|
-
import functools
|
|
14
13
|
from collections.abc import AsyncGenerator
|
|
15
14
|
from contextlib import asynccontextmanager
|
|
16
|
-
from
|
|
17
|
-
from typing import Any, Callable
|
|
15
|
+
from typing import Any
|
|
18
16
|
from uuid import UUID
|
|
19
17
|
|
|
20
18
|
from anyio import CancelScope, get_cancelled_exc_class
|
|
@@ -22,9 +20,7 @@ from redis.asyncio import Redis as AIORedis
|
|
|
22
20
|
from redis.asyncio.client import Pipeline, PubSub
|
|
23
21
|
from structlog import get_logger
|
|
24
22
|
|
|
25
|
-
from orchestrator.services.subscriptions import _generate_etag
|
|
26
23
|
from orchestrator.settings import app_settings
|
|
27
|
-
from orchestrator.utils.json import PY_JSON_TYPES, json_dumps, json_loads
|
|
28
24
|
from orchestrator.utils.redis_client import (
|
|
29
25
|
create_redis_asyncio_client,
|
|
30
26
|
create_redis_client,
|
|
@@ -37,52 +33,6 @@ cache = create_redis_client(app_settings.CACHE_URI)
|
|
|
37
33
|
ONE_WEEK = 3600 * 24 * 7
|
|
38
34
|
|
|
39
35
|
|
|
40
|
-
def caching_models_enabled() -> bool:
|
|
41
|
-
return getenv("AIOCACHE_DISABLE", "0") == "0" and app_settings.CACHE_DOMAIN_MODELS
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
def to_redis(subscription: dict[str, Any]) -> str | None:
|
|
45
|
-
if caching_models_enabled():
|
|
46
|
-
logger.info("Setting cache for subscription", subscription=subscription["subscription_id"])
|
|
47
|
-
etag = _generate_etag(subscription)
|
|
48
|
-
cache.set(f"orchestrator:domain:{subscription['subscription_id']}", json_dumps(subscription), ex=ONE_WEEK)
|
|
49
|
-
cache.set(f"orchestrator:domain:etag:{subscription['subscription_id']}", etag, ex=ONE_WEEK)
|
|
50
|
-
return etag
|
|
51
|
-
|
|
52
|
-
logger.warning("Caching disabled, not caching subscription", subscription=subscription["subscription_id"])
|
|
53
|
-
return None
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
def from_redis(subscription_id: UUID) -> tuple[PY_JSON_TYPES, str] | None:
|
|
57
|
-
log = logger.bind(subscription_id=subscription_id)
|
|
58
|
-
|
|
59
|
-
if app_settings.ENABLE_SUBSCRIPTION_MODEL_OPTIMIZATIONS:
|
|
60
|
-
# TODO #900 remove toggle and remove usage of this function in get_subscription_dict
|
|
61
|
-
log.info("Using SubscriptionModel optimization, not loading subscription from redis cache")
|
|
62
|
-
return None
|
|
63
|
-
|
|
64
|
-
if caching_models_enabled():
|
|
65
|
-
log.debug("Try to retrieve subscription from cache")
|
|
66
|
-
obj = cache.get(f"orchestrator:domain:{subscription_id}")
|
|
67
|
-
etag = cache.get(f"orchestrator:domain:etag:{subscription_id}")
|
|
68
|
-
if obj and etag:
|
|
69
|
-
log.info("Retrieved subscription from cache")
|
|
70
|
-
return json_loads(obj), etag.decode("utf-8")
|
|
71
|
-
log.info("Subscription not found in cache")
|
|
72
|
-
return None
|
|
73
|
-
log.warning("Caching disabled, not loading subscription")
|
|
74
|
-
return None
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
def delete_from_redis(subscription_id: UUID) -> None:
|
|
78
|
-
if caching_models_enabled():
|
|
79
|
-
logger.info("Deleting subscription object from cache", subscription_id=subscription_id)
|
|
80
|
-
cache.delete(f"orchestrator:domain:{subscription_id}")
|
|
81
|
-
cache.delete(f"orchestrator:domain:etag:{subscription_id}")
|
|
82
|
-
else:
|
|
83
|
-
logger.warning("Caching disabled, not deleting subscription", subscription=subscription_id)
|
|
84
|
-
|
|
85
|
-
|
|
86
36
|
def default_get_subscription_id(data: Any) -> UUID:
|
|
87
37
|
if hasattr(data, "subscription_id"):
|
|
88
38
|
return data.subscription_id
|
|
@@ -91,22 +41,6 @@ def default_get_subscription_id(data: Any) -> UUID:
|
|
|
91
41
|
return data
|
|
92
42
|
|
|
93
43
|
|
|
94
|
-
def delete_subscription_from_redis(
|
|
95
|
-
extract_fn: Callable[..., UUID] = default_get_subscription_id,
|
|
96
|
-
) -> Callable[[Callable[..., Any]], Callable[..., Any]]:
|
|
97
|
-
def _delete_subscription_from_redis(func: Callable[..., Any]) -> Callable[..., Any]:
|
|
98
|
-
@functools.wraps(func)
|
|
99
|
-
async def wrapper(*args: tuple, **kwargs: dict[str, Any]) -> Any:
|
|
100
|
-
data = await func(*args, **kwargs)
|
|
101
|
-
key = extract_fn(data)
|
|
102
|
-
delete_from_redis(key)
|
|
103
|
-
return data
|
|
104
|
-
|
|
105
|
-
return wrapper
|
|
106
|
-
|
|
107
|
-
return _delete_subscription_from_redis
|
|
108
|
-
|
|
109
|
-
|
|
110
44
|
async def delete_keys_matching_pattern(_cache: AIORedis, pattern: str, chunksize: int = 5000) -> int:
|
|
111
45
|
"""Delete all keys matching the given pattern.
|
|
112
46
|
|
|
@@ -13,11 +13,10 @@
|
|
|
13
13
|
from orchestrator.db import db
|
|
14
14
|
from orchestrator.forms import SubmitFormPage
|
|
15
15
|
from orchestrator.services import subscriptions
|
|
16
|
-
from orchestrator.settings import app_settings
|
|
17
16
|
from orchestrator.targets import Target
|
|
18
17
|
from orchestrator.utils.json import to_serializable
|
|
19
|
-
from orchestrator.workflow import StepList,
|
|
20
|
-
from orchestrator.workflows.steps import
|
|
18
|
+
from orchestrator.workflow import StepList, done, init, step, workflow
|
|
19
|
+
from orchestrator.workflows.steps import store_process_subscription
|
|
21
20
|
from orchestrator.workflows.utils import wrap_modify_initial_input_form
|
|
22
21
|
from pydantic_forms.types import FormGenerator, State, UUIDstr
|
|
23
22
|
from pydantic_forms.validators import LongText
|
|
@@ -54,11 +53,4 @@ def store_subscription_note(subscription_id: UUIDstr, note: str) -> State:
|
|
|
54
53
|
|
|
55
54
|
@workflow("Modify Note", initial_input_form=wrap_modify_initial_input_form(initial_input_form), target=Target.MODIFY)
|
|
56
55
|
def modify_note() -> StepList:
|
|
57
|
-
|
|
58
|
-
return (
|
|
59
|
-
init
|
|
60
|
-
>> store_process_subscription(Target.MODIFY)
|
|
61
|
-
>> store_subscription_note
|
|
62
|
-
>> push_subscriptions(cache_domain_models)
|
|
63
|
-
>> done
|
|
64
|
-
)
|
|
56
|
+
return init >> store_process_subscription(Target.MODIFY) >> store_subscription_note >> done
|
orchestrator/workflows/steps.py
CHANGED
|
@@ -11,22 +11,18 @@
|
|
|
11
11
|
# See the License for the specific language governing permissions and
|
|
12
12
|
# limitations under the License.
|
|
13
13
|
from copy import deepcopy
|
|
14
|
-
from typing import Any
|
|
15
|
-
from uuid import UUID
|
|
16
14
|
|
|
17
15
|
import structlog
|
|
18
16
|
from pydantic import ValidationError
|
|
19
17
|
|
|
20
18
|
from orchestrator.db import db
|
|
21
19
|
from orchestrator.db.models import ProcessSubscriptionTable
|
|
22
|
-
from orchestrator.domain.base import
|
|
20
|
+
from orchestrator.domain.base import SubscriptionModel
|
|
23
21
|
from orchestrator.services.settings import reset_search_index
|
|
24
|
-
from orchestrator.services.subscriptions import
|
|
22
|
+
from orchestrator.services.subscriptions import get_subscription
|
|
25
23
|
from orchestrator.targets import Target
|
|
26
24
|
from orchestrator.types import SubscriptionLifecycle
|
|
27
25
|
from orchestrator.utils.json import to_serializable
|
|
28
|
-
from orchestrator.utils.redis import delete_from_redis, to_redis
|
|
29
|
-
from orchestrator.websocket import sync_invalidate_subscription_cache
|
|
30
26
|
from orchestrator.workflow import Step, step
|
|
31
27
|
from pydantic_forms.types import State, UUIDstr
|
|
32
28
|
|
|
@@ -138,86 +134,6 @@ def set_status(status: SubscriptionLifecycle) -> Step:
|
|
|
138
134
|
return _set_status
|
|
139
135
|
|
|
140
136
|
|
|
141
|
-
@step("Remove domain model from cache")
|
|
142
|
-
def remove_domain_model_from_cache(
|
|
143
|
-
workflow_name: str, subscription: SubscriptionModel | None = None, subscription_id: UUID | None = None
|
|
144
|
-
) -> State:
|
|
145
|
-
"""Remove the domain model from the cache if it exists.
|
|
146
|
-
|
|
147
|
-
Args:
|
|
148
|
-
workflow_name: The workflow name
|
|
149
|
-
subscription: Subscription Model
|
|
150
|
-
subscription_id: The subscription id
|
|
151
|
-
|
|
152
|
-
Returns:
|
|
153
|
-
State
|
|
154
|
-
|
|
155
|
-
"""
|
|
156
|
-
|
|
157
|
-
if not (subscription or subscription_id):
|
|
158
|
-
logger.warning("No subscription found in this workflow", workflow_name=workflow_name)
|
|
159
|
-
return {"deleted_subscription_id": None}
|
|
160
|
-
if subscription:
|
|
161
|
-
delete_from_redis(subscription.subscription_id)
|
|
162
|
-
elif subscription_id:
|
|
163
|
-
delete_from_redis(subscription_id)
|
|
164
|
-
|
|
165
|
-
return {"deleted_subscription_id": subscription_id or subscription.subscription_id} # type: ignore[union-attr]
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
@step("Cache Subscription and related subscriptions")
|
|
169
|
-
def cache_domain_models(workflow_name: str, subscription: SubscriptionModel | None = None) -> State: # noqa: C901
|
|
170
|
-
"""Attempt to cache all Subscriptions once they have been touched once.
|
|
171
|
-
|
|
172
|
-
Args:
|
|
173
|
-
workflow_name: The Workflow Name
|
|
174
|
-
subscription: The Subscription if it exists.
|
|
175
|
-
|
|
176
|
-
Returns:
|
|
177
|
-
Returns State.
|
|
178
|
-
|
|
179
|
-
"""
|
|
180
|
-
cached_subscription_ids: set[UUID] = set()
|
|
181
|
-
if not subscription:
|
|
182
|
-
logger.warning("No subscription found in this workflow", workflow_name=workflow_name)
|
|
183
|
-
return {"cached_subscription_ids": cached_subscription_ids}
|
|
184
|
-
|
|
185
|
-
def _cache_other_subscriptions(product_block: ProductBlockModel) -> None:
|
|
186
|
-
for field in product_block.model_fields:
|
|
187
|
-
# subscription_instance is a ProductBlockModel or an arbitrary type
|
|
188
|
-
subscription_instance: ProductBlockModel | Any = getattr(product_block, field)
|
|
189
|
-
# If subscription_instance is a list, we need to step into it and loop.
|
|
190
|
-
if isinstance(subscription_instance, list):
|
|
191
|
-
for item in subscription_instance:
|
|
192
|
-
if isinstance(item, ProductBlockModel):
|
|
193
|
-
_cache_other_subscriptions(item)
|
|
194
|
-
|
|
195
|
-
# If subscription_instance is a ProductBlockModel check the owner_subscription_id to decide the cache
|
|
196
|
-
elif isinstance(subscription_instance, ProductBlockModel):
|
|
197
|
-
_cache_other_subscriptions(subscription_instance)
|
|
198
|
-
if not subscription_instance.owner_subscription_id == subscription.subscription_id:
|
|
199
|
-
cached_subscription_ids.add(subscription_instance.owner_subscription_id)
|
|
200
|
-
|
|
201
|
-
for field in subscription.model_fields:
|
|
202
|
-
# There always is a single Root Product Block, it cannot be a list, so no need to check.
|
|
203
|
-
instance: ProductBlockModel | Any = getattr(subscription, field)
|
|
204
|
-
if isinstance(instance, ProductBlockModel):
|
|
205
|
-
_cache_other_subscriptions(instance)
|
|
206
|
-
|
|
207
|
-
# Cache all the sub subscriptions
|
|
208
|
-
for subscription_id in cached_subscription_ids:
|
|
209
|
-
subscription_model = SubscriptionModel.from_subscription(subscription_id)
|
|
210
|
-
to_redis(build_extended_domain_model(subscription_model))
|
|
211
|
-
sync_invalidate_subscription_cache(subscription.subscription_id, invalidate_all=False)
|
|
212
|
-
|
|
213
|
-
# Cache the main subscription
|
|
214
|
-
to_redis(build_extended_domain_model(subscription))
|
|
215
|
-
cached_subscription_ids.add(subscription.subscription_id)
|
|
216
|
-
sync_invalidate_subscription_cache(subscription.subscription_id)
|
|
217
|
-
|
|
218
|
-
return {"cached_subscription_ids": cached_subscription_ids}
|
|
219
|
-
|
|
220
|
-
|
|
221
137
|
@step("Refresh subscription search index")
|
|
222
138
|
def refresh_subscription_search_index() -> State:
|
|
223
139
|
try:
|
orchestrator/workflows/utils.py
CHANGED
|
@@ -24,16 +24,13 @@ from oauth2_lib.fastapi import OIDCUserModel
|
|
|
24
24
|
from orchestrator.db import ProductTable, SubscriptionTable, db
|
|
25
25
|
from orchestrator.forms.validators import ProductId
|
|
26
26
|
from orchestrator.services import subscriptions
|
|
27
|
-
from orchestrator.settings import app_settings
|
|
28
27
|
from orchestrator.targets import Target
|
|
29
28
|
from orchestrator.types import SubscriptionLifecycle
|
|
30
29
|
from orchestrator.utils.errors import StaleDataError
|
|
31
|
-
from orchestrator.utils.redis import caching_models_enabled
|
|
32
30
|
from orchestrator.utils.state import form_inject_args
|
|
33
31
|
from orchestrator.utils.validate_data_version import validate_data_version
|
|
34
|
-
from orchestrator.workflow import Step, StepList, Workflow, begin,
|
|
32
|
+
from orchestrator.workflow import Step, StepList, Workflow, begin, done, init, make_workflow, step
|
|
35
33
|
from orchestrator.workflows.steps import (
|
|
36
|
-
cache_domain_models,
|
|
37
34
|
refresh_subscription_search_index,
|
|
38
35
|
resync,
|
|
39
36
|
set_status,
|
|
@@ -198,8 +195,6 @@ modify_initial_input_form_generator = None
|
|
|
198
195
|
|
|
199
196
|
validate_initial_input_form_generator = wrap_modify_initial_input_form(modify_initial_input_form_generator)
|
|
200
197
|
|
|
201
|
-
push_domain_models = conditional(lambda _: caching_models_enabled())
|
|
202
|
-
|
|
203
198
|
|
|
204
199
|
def create_workflow(
|
|
205
200
|
description: str,
|
|
@@ -228,7 +223,6 @@ def create_workflow(
|
|
|
228
223
|
>> (additional_steps or StepList())
|
|
229
224
|
>> set_status(status)
|
|
230
225
|
>> resync
|
|
231
|
-
>> push_domain_models(cache_domain_models)
|
|
232
226
|
>> refresh_subscription_search_index
|
|
233
227
|
>> done
|
|
234
228
|
)
|
|
@@ -270,11 +264,9 @@ def modify_workflow(
|
|
|
270
264
|
init
|
|
271
265
|
>> store_process_subscription(Target.MODIFY)
|
|
272
266
|
>> unsync
|
|
273
|
-
>> push_domain_models(cache_domain_models)
|
|
274
267
|
>> f()
|
|
275
268
|
>> (additional_steps or StepList())
|
|
276
269
|
>> resync
|
|
277
|
-
>> push_domain_models(cache_domain_models)
|
|
278
270
|
>> refresh_subscription_search_index
|
|
279
271
|
>> done
|
|
280
272
|
)
|
|
@@ -316,12 +308,10 @@ def terminate_workflow(
|
|
|
316
308
|
init
|
|
317
309
|
>> store_process_subscription(Target.TERMINATE)
|
|
318
310
|
>> unsync
|
|
319
|
-
>> push_domain_models(cache_domain_models)
|
|
320
311
|
>> f()
|
|
321
312
|
>> (additional_steps or StepList())
|
|
322
313
|
>> set_status(SubscriptionLifecycle.TERMINATED)
|
|
323
314
|
>> resync
|
|
324
|
-
>> push_domain_models(cache_domain_models)
|
|
325
315
|
>> refresh_subscription_search_index
|
|
326
316
|
>> done
|
|
327
317
|
)
|
|
@@ -352,17 +342,7 @@ def validate_workflow(description: str) -> Callable[[Callable[[], StepList]], Wo
|
|
|
352
342
|
"""
|
|
353
343
|
|
|
354
344
|
def _validate_workflow(f: Callable[[], StepList]) -> Workflow:
|
|
355
|
-
|
|
356
|
-
steplist = (
|
|
357
|
-
init
|
|
358
|
-
>> store_process_subscription(Target.SYSTEM)
|
|
359
|
-
>> unsync_unchecked
|
|
360
|
-
>> push_subscriptions(cache_domain_models)
|
|
361
|
-
>> f()
|
|
362
|
-
>> resync
|
|
363
|
-
>> push_subscriptions(cache_domain_models)
|
|
364
|
-
>> done
|
|
365
|
-
)
|
|
345
|
+
steplist = init >> store_process_subscription(Target.SYSTEM) >> unsync_unchecked >> f() >> resync >> done
|
|
366
346
|
|
|
367
347
|
return make_workflow(f, description, validate_initial_input_form_generator, Target.SYSTEM, steplist)
|
|
368
348
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: orchestrator-core
|
|
3
|
-
Version:
|
|
3
|
+
Version: 4.0.0rc1
|
|
4
4
|
Summary: This is the orchestrator workflow engine.
|
|
5
5
|
Requires-Python: >=3.11,<3.14
|
|
6
6
|
Classifier: Intended Audience :: Information Technology
|
|
@@ -35,24 +35,24 @@ Requires-Dist: deprecated
|
|
|
35
35
|
Requires-Dist: deepmerge==2.0
|
|
36
36
|
Requires-Dist: fastapi~=0.115.2
|
|
37
37
|
Requires-Dist: fastapi-etag==0.4.0
|
|
38
|
-
Requires-Dist: more-itertools~=10.
|
|
38
|
+
Requires-Dist: more-itertools~=10.7.0
|
|
39
39
|
Requires-Dist: itsdangerous
|
|
40
40
|
Requires-Dist: Jinja2==3.1.6
|
|
41
|
-
Requires-Dist: orjson==3.10.
|
|
41
|
+
Requires-Dist: orjson==3.10.18
|
|
42
42
|
Requires-Dist: psycopg2-binary==2.9.10
|
|
43
43
|
Requires-Dist: pydantic[email]~=2.8.2
|
|
44
|
-
Requires-Dist: pydantic-settings~=2.
|
|
44
|
+
Requires-Dist: pydantic-settings~=2.9.1
|
|
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.2
|
|
48
48
|
Requires-Dist: redis==5.1.1
|
|
49
49
|
Requires-Dist: schedule==1.1.0
|
|
50
50
|
Requires-Dist: semver==3.0.4
|
|
51
|
-
Requires-Dist: sentry-sdk[fastapi]~=2.
|
|
51
|
+
Requires-Dist: sentry-sdk[fastapi]~=2.27.0
|
|
52
52
|
Requires-Dist: SQLAlchemy==2.0.40
|
|
53
53
|
Requires-Dist: SQLAlchemy-Utils==0.41.2
|
|
54
54
|
Requires-Dist: structlog
|
|
55
|
-
Requires-Dist: typer==0.15.
|
|
55
|
+
Requires-Dist: typer==0.15.3
|
|
56
56
|
Requires-Dist: uvicorn[standard]~=0.34.0
|
|
57
57
|
Requires-Dist: nwa-stdlib~=1.9.0
|
|
58
58
|
Requires-Dist: oauth2-lib~=2.4.0
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
orchestrator/__init__.py,sha256=
|
|
1
|
+
orchestrator/__init__.py,sha256=VeHQewmn2Fz_VeMN_e71lAH_9sS-t7zhdO8h30dYbKo,1066
|
|
2
2
|
orchestrator/app.py,sha256=VN54_Zsx5x_3ym8aFadATg67a4J5lv8H-pxnPlR3RkM,11668
|
|
3
3
|
orchestrator/exception_handlers.py,sha256=UsW3dw8q0QQlNLcV359bIotah8DYjMsj2Ts1LfX4ClY,1268
|
|
4
4
|
orchestrator/log_config.py,sha256=1tPRX5q65e57a6a_zEii_PFK8SzWT0mnA5w2sKg4hh8,1853
|
|
5
5
|
orchestrator/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
6
|
orchestrator/security.py,sha256=iXFxGxab54aav7oHEKLAVkTgrQMJGHy6IYLojEnD7gI,2422
|
|
7
|
-
orchestrator/settings.py,sha256=
|
|
7
|
+
orchestrator/settings.py,sha256=21BT1SviPllSL4-M1Qc-8zdgF_Sh7p79WC8sR_AmTmE,3826
|
|
8
8
|
orchestrator/targets.py,sha256=ykjTGK7CozFaltNaxQcK90P4Cc1Qvf-W8dFztxtZhRQ,776
|
|
9
9
|
orchestrator/types.py,sha256=qzs7xx5AYRmKbpYRyJJP3wuDb0W0bcAzefCN0RWLAco,15459
|
|
10
10
|
orchestrator/version.py,sha256=b58e08lxs47wUNXv0jXFO_ykpksmytuzEXD4La4W-NQ,1366
|
|
@@ -22,7 +22,7 @@ orchestrator/api/api_v1/endpoints/product_blocks.py,sha256=kZ6ywIOsS_S2qGq7RvZ4K
|
|
|
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
|
|
24
24
|
orchestrator/api/api_v1/endpoints/settings.py,sha256=QPBwrRGqBlYHNRnADKQ5hpj74X2DB5lROu8KwVnyN_0,6226
|
|
25
|
-
orchestrator/api/api_v1/endpoints/subscription_customer_descriptions.py,sha256=
|
|
25
|
+
orchestrator/api/api_v1/endpoints/subscription_customer_descriptions.py,sha256=1_6LtgQleoq3M6z_W-Qz__Bj3OFUweoPrUqHMwSH6AM,3288
|
|
26
26
|
orchestrator/api/api_v1/endpoints/subscriptions.py,sha256=EwkWBztI9xSMPkol49SM5csECthyu7HC38AhuW7pWUE,8724
|
|
27
27
|
orchestrator/api/api_v1/endpoints/translations.py,sha256=dIWh_fCnZZUxJoGiNeJ49DK_xpf75IpR_0EIMSvzIvY,963
|
|
28
28
|
orchestrator/api/api_v1/endpoints/user.py,sha256=RyI32EXVu6I-IxWjz0XB5zQWzzLL60zKXLgLqLH02xU,1827
|
|
@@ -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=ez6JzQ3IKVkC_oLAkVlIIiI8Do7hXbdcPKCvUSLxRog,7962
|
|
109
|
-
orchestrator/db/models.py,sha256=
|
|
109
|
+
orchestrator/db/models.py,sha256=0WJOgKGa6h_0leIWtNxim0Kni5pWTbprJrzyiGRchio,27218
|
|
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
|
|
@@ -142,9 +142,9 @@ orchestrator/distlock/managers/__init__.py,sha256=ImIkNsrXcyE7-NgRWqEhUXUuUzda9K
|
|
|
142
142
|
orchestrator/distlock/managers/memory_distlock_manager.py,sha256=HWQafcVKBF-Cka_wukZZ1GM69AWPVOpJPje3quIebQ8,3114
|
|
143
143
|
orchestrator/distlock/managers/redis_distlock_manager.py,sha256=DXtMhC8qtxiFO6xU9qYXHZQnCLjlmGBpeyfLA0vbRP0,3369
|
|
144
144
|
orchestrator/domain/__init__.py,sha256=20DhXQPKY0g3rTgCkRlNDY58sLviToOVF8NPoex9WJc,936
|
|
145
|
-
orchestrator/domain/base.py,sha256=
|
|
145
|
+
orchestrator/domain/base.py,sha256=jjMxJvt0GyaTff_z490lmkqDCtitkh0oA4GygB60n4s,69939
|
|
146
146
|
orchestrator/domain/context_cache.py,sha256=vT1a01MBSBIaokoShK9KwjItd7abNmz7cXaF67VRZK8,2508
|
|
147
|
-
orchestrator/domain/customer_description.py,sha256=
|
|
147
|
+
orchestrator/domain/customer_description.py,sha256=RU_pcgCIZjjFfDsY45lfV0z6ATlS1NXtB0E7eH3UcYQ,3190
|
|
148
148
|
orchestrator/domain/helpers.py,sha256=D9O2duhCAZGmm39u-9ggvU-X2JsCbIS607kF77-r8QM,2549
|
|
149
149
|
orchestrator/domain/lifecycle.py,sha256=kGR0AFVOSUBlzdhgRr11CUnF26wbBYIjz8uKb_qPCg0,2922
|
|
150
150
|
orchestrator/domain/subscription_instance_transform.py,sha256=j_d49dFcSss0dl-BHS-ev2faLbE0y8hLvCfrzui6C74,4360
|
|
@@ -165,7 +165,7 @@ orchestrator/graphql/extensions/model_cache.py,sha256=1uhMRjBs9eK7zJ1Y6P6BopX068
|
|
|
165
165
|
orchestrator/graphql/extensions/stats.py,sha256=pGhEBQg45XvqZhRobcrCSGwt5AGmR3gflsm1dYiIg5g,2018
|
|
166
166
|
orchestrator/graphql/loaders/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
167
167
|
orchestrator/graphql/loaders/subscriptions.py,sha256=31zE2WC7z-tPIUmVpU1QWOJvNbLvF7sYgY7JAQ6OPJg,1856
|
|
168
|
-
orchestrator/graphql/mutations/customer_description.py,sha256=
|
|
168
|
+
orchestrator/graphql/mutations/customer_description.py,sha256=zm_X1yvWl4qC97_rYUYSF-1q1gFrQX6fDrzQKhguDYs,3359
|
|
169
169
|
orchestrator/graphql/mutations/start_process.py,sha256=8vLVvmBwL1ujbZJoI_8YE3VAgI-J2RTzgrTZJC8THZ4,1576
|
|
170
170
|
orchestrator/graphql/resolvers/__init__.py,sha256=EEw9NO4LAryfrpkLlgsNQ9rytKd0usBDx95OURRV6sg,1031
|
|
171
171
|
orchestrator/graphql/resolvers/customer.py,sha256=tq06MtMoaqFwqn3YQvSv0VmROW7QJZRJp1ykO4tUhck,934
|
|
@@ -231,6 +231,7 @@ orchestrator/migrations/versions/schema/2024-09-27_460ec6748e37_add_uuid_search_
|
|
|
231
231
|
orchestrator/migrations/versions/schema/2025-01-08_4c5859620539_add_version_column_to_subscription.py,sha256=xAhe74U0ZiVRo9Z8Uq7491RBbATMMUnYpTBjbG-BYL0,1690
|
|
232
232
|
orchestrator/migrations/versions/schema/2025-01-19_4fjdn13f83ga_add_validate_product_type_task.py,sha256=O0GfCISIDnyohGf3Ot_2HKedGRbMqLVox6t7Wd3PMvo,894
|
|
233
233
|
orchestrator/migrations/versions/schema/2025-02-12_bac6be6f2b4f_added_input_state_table.py,sha256=RZpLkWP1yekeZ68feO5v4LZYluKvnnIKRNDCE4tI9HM,1753
|
|
234
|
+
orchestrator/migrations/versions/schema/2025-02-20_68d14db1b8da_make_workflow_description_mandatory.py,sha256=qabQWLjPWU-1-uLTFwcEyxyMQK89UPqUdl3Q-HSGKTI,847
|
|
234
235
|
orchestrator/migrations/versions/schema/2025-03-06_42b3d076a85b_subscription_instance_as_json_function.py,sha256=jtwDFOh-NlE31aH5dFmbynb23TZN6Mkzevxx-KLP7KE,776
|
|
235
236
|
orchestrator/migrations/versions/schema/2025-03-06_42b3d076a85b_subscription_instance_as_json_function.sql,sha256=hPldk0DAesUbHv3Qd_N7U-cAk-t1wIgxt4FOA120gQ8,1776
|
|
236
237
|
orchestrator/migrations/versions/schema/2025-04-09_fc5c993a4b4a_add_cascade_constraint_on_processes_.py,sha256=6kHRNSZxUze2jy7b8uRvkt5mzsax10Z-Z3lsACtPLRM,1067
|
|
@@ -257,12 +258,12 @@ orchestrator/services/celery.py,sha256=W37UNc4hbUS2SKjVmawsnF5wukmEfIdipsTESv_EO
|
|
|
257
258
|
orchestrator/services/fixed_inputs.py,sha256=kyz7s2HLzyDulvcq-ZqefTw1om86COvyvTjz0_5CmgI,876
|
|
258
259
|
orchestrator/services/input_state.py,sha256=HF7wl9fWdaAW8pdCCqbuYoKyNj8dY0g8Ff8vXis8z5A,2211
|
|
259
260
|
orchestrator/services/process_broadcast_thread.py,sha256=D44YbjF8mRqGuznkRUV4SoRn1J0lfy_x1H508GnSVlU,4649
|
|
260
|
-
orchestrator/services/processes.py,sha256=
|
|
261
|
+
orchestrator/services/processes.py,sha256=cIesTJNl-kC2oLvzWOJE2uzmwcqZMWHLlgU-9qcVvac,30555
|
|
261
262
|
orchestrator/services/products.py,sha256=BP4KyE8zO-8z7Trrs5T6zKBOw53S9BfBJnHWI3p6u5Y,1943
|
|
262
263
|
orchestrator/services/resource_types.py,sha256=_QBy_JOW_X3aSTqH0CuLrq4zBJL0p7Q-UDJUcuK2_qc,884
|
|
263
264
|
orchestrator/services/settings.py,sha256=u-834F4KWloXS8zi7R9mp-D3cjl-rbVjKJRU35IqhXo,2723
|
|
264
265
|
orchestrator/services/subscription_relations.py,sha256=9C126TUfFvyBe7y4x007kH_dvxJ9pZ1zSnaWeH6HC5k,12261
|
|
265
|
-
orchestrator/services/subscriptions.py,sha256=
|
|
266
|
+
orchestrator/services/subscriptions.py,sha256=mXU88SzugwQGnLG0-aaa9YZXTr5rt4LAEOChCb7BF20,27116
|
|
266
267
|
orchestrator/services/tasks.py,sha256=NjPkuauQoh9UJDcjA7OcKFgPk0i6NoKdDO7HlpGbBJ8,6575
|
|
267
268
|
orchestrator/services/translations.py,sha256=GyP8soUFGej8AS8uulBsk10CCK6Kwfjv9AHMFm3ElQY,1713
|
|
268
269
|
orchestrator/services/workflows.py,sha256=oH7klit4kv2NGo-BACWA0ZtajVMSJAxG5m-kM6TXIMI,3742
|
|
@@ -275,11 +276,11 @@ orchestrator/utils/enrich_process.py,sha256=o_QSy5Q4wn1SMHhzVOw6bp7uhDXr7GhAIWRD
|
|
|
275
276
|
orchestrator/utils/errors.py,sha256=6FxvXrITmRjP5bYnJJ3CxjAwA5meNjRAVYouz4TWKkU,4653
|
|
276
277
|
orchestrator/utils/fixed_inputs.py,sha256=pnL6I_19VMp_Bny8SYjSzVFNvTFDyeCxFFOWGhTnDiQ,2665
|
|
277
278
|
orchestrator/utils/functional.py,sha256=X1MDNwHmkU3-8mFb21m31HGlcfc5TygliXR0sXN3-rU,8304
|
|
278
|
-
orchestrator/utils/get_subscription_dict.py,sha256=
|
|
279
|
+
orchestrator/utils/get_subscription_dict.py,sha256=hctkFvD3U6LpygNwz2uesRMdnXSY-PaohBqPATsi9r4,694
|
|
279
280
|
orchestrator/utils/get_updated_properties.py,sha256=egVZ0R5LNJ4e51Z8SXlU8cmb4tXxG-xb1d7OKwh-7xI,1322
|
|
280
281
|
orchestrator/utils/helpers.py,sha256=NjUF3IvWdnLulliP8-JQvGGGpHrh0vs0Vm092ynw-ss,3212
|
|
281
282
|
orchestrator/utils/json.py,sha256=7386sdqkrKYyy4sbn5NscwctH_v1hLyw5172P__rU3g,8341
|
|
282
|
-
orchestrator/utils/redis.py,sha256=
|
|
283
|
+
orchestrator/utils/redis.py,sha256=BjUNmrKx8YVyJIucl2mhXubK6WV-49OnAU6rPMOZpM0,4469
|
|
283
284
|
orchestrator/utils/redis_client.py,sha256=9rhsvedjK_CyClAjUicQyge0mVIViATqKFGZyjBY3XA,1384
|
|
284
285
|
orchestrator/utils/search_query.py,sha256=ji5LHtrzohGz6b1IG41cnPdpWXzLEzz4SGWgHly_yfU,16205
|
|
285
286
|
orchestrator/utils/state.py,sha256=RYKVlvKDBfsBdDk9wHjZKBTlQJbV4SqtCotAlTA2-bI,14021
|
|
@@ -290,17 +291,17 @@ orchestrator/websocket/websocket_manager.py,sha256=hwlG9FDXcNU42jDNNsPMQLIyrvEpG
|
|
|
290
291
|
orchestrator/websocket/managers/broadcast_websocket_manager.py,sha256=fwoSgTjkHJ2GmsLTU9dqQpAA9i8b1McPu7gLNzxtfG4,5401
|
|
291
292
|
orchestrator/websocket/managers/memory_websocket_manager.py,sha256=lF5EEx1iFMCGEkTbItTDr88NENMSaSeG1QrJ7teoPkY,3324
|
|
292
293
|
orchestrator/workflows/__init__.py,sha256=NzIGGI-8SNAwCk2YqH6sHhEWbgAY457ntDwjO15N8v4,4131
|
|
293
|
-
orchestrator/workflows/modify_note.py,sha256=
|
|
294
|
+
orchestrator/workflows/modify_note.py,sha256=l6QtijRPv8gnHxzwTz_4nWIPcZ0FcKQh_yFbtjYEDMg,2163
|
|
294
295
|
orchestrator/workflows/removed_workflow.py,sha256=V0Da5TEdfLdZZKD38ig-MTp3_IuE7VGqzHHzvPYQmLI,909
|
|
295
|
-
orchestrator/workflows/steps.py,sha256=
|
|
296
|
-
orchestrator/workflows/utils.py,sha256=
|
|
296
|
+
orchestrator/workflows/steps.py,sha256=ulpheoHaCOE1qh71Bja4KW4pItQh1Z6q4QU4tn5GtNk,6067
|
|
297
|
+
orchestrator/workflows/utils.py,sha256=ePXTb_0eO25qvKzC6ZO3FdVQU0sWhglJo7hX6nsO4_w,13776
|
|
297
298
|
orchestrator/workflows/tasks/__init__.py,sha256=GyHNfEFCGKQwRiN6rQmvSRH2iYX7npjMZn97n8XzmLU,571
|
|
298
299
|
orchestrator/workflows/tasks/cleanup_tasks_log.py,sha256=BfWYbPXhnLAHUJ0mlODDnjZnQQAvKCZJDVTwbwOWI04,1624
|
|
299
300
|
orchestrator/workflows/tasks/resume_workflows.py,sha256=MzJqlSXUvKStkT7NGzxZyRlfAer_ezYm-kjUqaZi0yc,2359
|
|
300
301
|
orchestrator/workflows/tasks/validate_product_type.py,sha256=UVX_6Kh8ueQs8ujLawnKVDdNc8UhWp_u69aNA8okR_w,3184
|
|
301
302
|
orchestrator/workflows/tasks/validate_products.py,sha256=i6jQME9N8sZZWo4pkNOS1Zgwh3eB2w66DnJi9k93yNk,8521
|
|
302
303
|
orchestrator/workflows/translations/en-GB.json,sha256=ST53HxkphFLTMjFHonykDBOZ7-P_KxksktZU3GbxLt0,846
|
|
303
|
-
orchestrator_core-
|
|
304
|
-
orchestrator_core-
|
|
305
|
-
orchestrator_core-
|
|
306
|
-
orchestrator_core-
|
|
304
|
+
orchestrator_core-4.0.0rc1.dist-info/licenses/LICENSE,sha256=b-aA5OZQuuBATmLKo_mln8CQrDPPhg3ghLzjPjLn4Tg,11409
|
|
305
|
+
orchestrator_core-4.0.0rc1.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
|
|
306
|
+
orchestrator_core-4.0.0rc1.dist-info/METADATA,sha256=PnOlFXhp5Z5svvnngGuSFa3pfteaT69k7PoqWbfwHjA,5032
|
|
307
|
+
orchestrator_core-4.0.0rc1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|