diff --git a/CHANGELOG.md b/CHANGELOG.md index ea34e0d690..928d55f603 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,12 @@ Changes are grouped as follows - `Fixed` for any bug fixes. - `Security` in case of vulnerabilities. +## [7.62.5] - 2024-09-26 +### Added +- Add new `client.workflows.triggers.upsert`, this allows upserts of triggers. +### Deprecated +- Deprecate `client.workflows.triggers.create`, as its functionality is covered by the new `client.workflows.triggers.upsert` + ## [7.62.4] - 2024-09-25 ### Fixed - In the CoreModel, `client.data_classes.data_modeling.cdm` the fields `isUploaded` and `uploadedTime` in diff --git a/cognite/client/_api/workflows.py b/cognite/client/_api/workflows.py index 715cd7a4c2..38f748f38c 100644 --- a/cognite/client/_api/workflows.py +++ b/cognite/client/_api/workflows.py @@ -23,6 +23,7 @@ WorkflowTriggerList, WorkflowTriggerRun, WorkflowTriggerRunList, + WorkflowTriggerUpsert, WorkflowUpsert, WorkflowVersion, WorkflowVersionId, @@ -56,29 +57,29 @@ def wrap_workflow_ids( class WorkflowTriggerAPI(APIClient): _RESOURCE_PATH = "/workflows/triggers" - def create( + def upsert( self, - workflow_trigger: WorkflowTriggerCreate, + workflow_trigger: WorkflowTriggerUpsert, client_credentials: ClientCredentials | dict | None = None, ) -> WorkflowTrigger: - """`Create a new trigger for a workflow. `_ + """`Create or update a trigger for a workflow. `_ Args: - workflow_trigger (WorkflowTriggerCreate): The workflow trigger specitification. + workflow_trigger (WorkflowTriggerUpsert): The workflow trigger specitification. client_credentials (ClientCredentials | dict | None): Specific credentials that should be used to trigger the workflow execution. When passed will take precedence over the current credentials. Returns: - WorkflowTrigger: The created workflow trigger specification. + WorkflowTrigger: The created or updated workflow trigger specification. Examples: - Create a new scheduled trigger for a workflow: + Create or update a scheduled trigger for a workflow: >>> from cognite.client import CogniteClient - >>> from cognite.client.data_classes.workflows import WorkflowTriggerCreate, WorkflowScheduledTriggerRule + >>> from cognite.client.data_classes.workflows import WorkflowTriggerUpsert, WorkflowScheduledTriggerRule >>> client = CogniteClient() - >>> client.workflows.triggers.create( - ... WorkflowTriggerCreate( + >>> client.workflows.triggers.upsert( + ... WorkflowTriggerUpsert( ... external_id="my_trigger", ... trigger_rule=WorkflowScheduledTriggerRule(cron_expression="0 0 * * *"), ... workflow_external_id="my_workflow", @@ -98,6 +99,46 @@ def create( ) return WorkflowTrigger._load(response.json().get("items")[0]) + # TODO: remove method and associated data classes in next release + def create( + self, + workflow_trigger: WorkflowTriggerCreate, + client_credentials: ClientCredentials | dict | None = None, + ) -> WorkflowTrigger: + """`[DEPRECATED] Create or update a trigger for a workflow. `_ + + This method is deprecated, use '.upsert' instead. It will be completely removed October 2024. + + Args: + workflow_trigger (WorkflowTriggerCreate): The workflow trigger specitification. + client_credentials (ClientCredentials | dict | None): Specific credentials that should be used to trigger the workflow execution. When passed will take precedence over the current credentials. + + Returns: + WorkflowTrigger: The created or updated workflow trigger specification. + + Examples: + + Create or update a scheduled trigger for a workflow: + + >>> from cognite.client import CogniteClient + >>> from cognite.client.data_classes.workflows import WorkflowTriggerCreate, WorkflowScheduledTriggerRule + >>> client = CogniteClient() + >>> client.workflows.triggers.create( + ... WorkflowTriggerCreate( + ... external_id="my_trigger", + ... trigger_rule=WorkflowScheduledTriggerRule(cron_expression="0 0 * * *"), + ... workflow_external_id="my_workflow", + ... workflow_version="1", + ... input={"a": 1, "b": 2}, + ... ) + ... ) + """ + warnings.warn( + "This method is deprecated, use '.upsert' instead. It will be removed in the next major release.", + UserWarning, + ) + return self.upsert(workflow_trigger, client_credentials) + def delete( self, external_id: str, @@ -288,9 +329,8 @@ def trigger( WorkflowExecution: No description. """ warnings.warn( - "This methods has been deprecated, use '.run' instead. It will be completely removed October 2024.", - DeprecationWarning, - stacklevel=2, + "This methods has been deprecated, use '.run' instead. It will completely removed in the next major release.", + UserWarning, ) return self.run(workflow_external_id, version, input, metadata, client_credentials) diff --git a/cognite/client/_version.py b/cognite/client/_version.py index 2eb31d4a93..8344819503 100644 --- a/cognite/client/_version.py +++ b/cognite/client/_version.py @@ -1,4 +1,4 @@ from __future__ import annotations -__version__ = "7.62.4" +__version__ = "7.62.5" __api_subversion__ = "20230101" diff --git a/cognite/client/data_classes/__init__.py b/cognite/client/data_classes/__init__.py index 3966f0ec82..fadaae74a9 100644 --- a/cognite/client/data_classes/__init__.py +++ b/cognite/client/data_classes/__init__.py @@ -305,10 +305,11 @@ WorkflowTaskExecution, WorkflowTrigger, WorkflowTriggerCreate, - WorkflowTriggerCreateList, WorkflowTriggerList, WorkflowTriggerRun, WorkflowTriggerRunList, + WorkflowTriggerUpsert, + WorkflowTriggerUpsertList, WorkflowUpsert, WorkflowUpsertList, WorkflowVersion, @@ -578,8 +579,9 @@ "WorkflowVersionUpsertList", "WorkflowTrigger", "WorkflowTriggerCreate", + "WorkflowTriggerUpsert", "WorkflowTriggerList", - "WorkflowTriggerCreateList", + "WorkflowTriggerUpsertList", "WorkflowTriggerRun", "WorkflowTriggerRunList", "HasName", diff --git a/cognite/client/data_classes/workflows.py b/cognite/client/data_classes/workflows.py index 6f69352036..70e5ef9085 100644 --- a/cognite/client/data_classes/workflows.py +++ b/cognite/client/data_classes/workflows.py @@ -1260,7 +1260,7 @@ def _load_trigger(cls, data: dict) -> WorkflowScheduledTriggerRule: } -class WorkflowTriggerCore(WriteableCogniteResource["WorkflowTriggerCreate"], ABC): +class WorkflowTriggerCore(WriteableCogniteResource["WorkflowTriggerUpsert"], ABC): """ This class represents a base class for a workflow trigger. @@ -1287,9 +1287,9 @@ def __init__( self.input = input -class WorkflowTriggerCreate(WorkflowTriggerCore): +class WorkflowTriggerUpsert(WorkflowTriggerCore): """ - This class represents a workflow trigger for creation. + This class represents a workflow trigger for upsertion. Args: external_id (str): The external ID provided by the client. Must be unique for the resource type. @@ -1313,7 +1313,7 @@ def dump(self, camel_case: bool = True) -> dict[str, Any]: return item @classmethod - def _load(cls, resource: dict, cognite_client: CogniteClient | None = None) -> WorkflowTriggerCreate: + def _load(cls, resource: dict, cognite_client: CogniteClient | None = None) -> WorkflowTriggerUpsert: return cls( external_id=resource["externalId"], workflow_external_id=resource["workflowExternalId"], @@ -1322,11 +1322,14 @@ def _load(cls, resource: dict, cognite_client: CogniteClient | None = None) -> W input=resource.get("input"), ) - def as_write(self) -> WorkflowTriggerCreate: + def as_write(self) -> WorkflowTriggerUpsert: """Returns this workflow trigger create instance.""" return self +WorkflowTriggerCreate = WorkflowTriggerUpsert + + class WorkflowTrigger(WorkflowTriggerCore): """ This class represents a workflow trigger. @@ -1390,9 +1393,9 @@ def _load(cls, resource: dict, cognite_client: CogniteClient | None = None) -> W last_updated_time=resource.get("lastUpdatedTime"), ) - def as_write(self) -> WorkflowTriggerCreate: + def as_write(self) -> WorkflowTriggerUpsert: """Returns this workflow trigger instance.""" - return WorkflowTriggerCreate( + return WorkflowTriggerUpsert( external_id=self.external_id, trigger_rule=self.trigger_rule, workflow_external_id=self.workflow_external_id, @@ -1401,20 +1404,20 @@ def as_write(self) -> WorkflowTriggerCreate: ) -class WorkflowTriggerCreateList(CogniteResourceList[WorkflowTriggerCreate]): - _RESOURCE = WorkflowTriggerCreate +class WorkflowTriggerUpsertList(CogniteResourceList[WorkflowTriggerUpsert]): + _RESOURCE = WorkflowTriggerUpsert -class WorkflowTriggerList(WriteableCogniteResourceList[WorkflowTriggerCreate, WorkflowTrigger]): +class WorkflowTriggerList(WriteableCogniteResourceList[WorkflowTriggerUpsert, WorkflowTrigger]): """ This class represents a list of workflow triggers. """ _RESOURCE = WorkflowTrigger - def as_write(self) -> WorkflowTriggerCreateList: - """Returns a WorkflowTriggerCreateList object with the same data.""" - return WorkflowTriggerCreateList([workflow_trigger.as_write() for workflow_trigger in self.data]) + def as_write(self) -> WorkflowTriggerUpsertList: + """Returns a WorkflowTriggerUpsertList object with the same data.""" + return WorkflowTriggerUpsertList([workflow_trigger.as_write() for workflow_trigger in self.data]) class WorkflowTriggerRun(CogniteResource): diff --git a/docs/source/data_workflows.rst b/docs/source/data_workflows.rst index 81bcc3a3e5..70b1eedfe1 100644 --- a/docs/source/data_workflows.rst +++ b/docs/source/data_workflows.rst @@ -73,6 +73,10 @@ Update Status of Async Task Workflow Triggers ------------------- +Create or update triggers for workflow executions +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. automethod:: cognite.client._api.workflows.WorkflowTriggerAPI.upsert + Create triggers for workflow executions ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. automethod:: cognite.client._api.workflows.WorkflowTriggerAPI.create diff --git a/pyproject.toml b/pyproject.toml index 3bd2817b7f..58821b1b67 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [tool.poetry] name = "cognite-sdk" -version = "7.62.4" +version = "7.62.5" description = "Cognite Python SDK" readme = "README.md" documentation = "https://cognite-sdk-python.readthedocs-hosted.com" diff --git a/tests/tests_integration/test_api/test_data_workflows.py b/tests/tests_integration/test_api/test_data_workflows.py index 92a54ca33f..6ec8ecce90 100644 --- a/tests/tests_integration/test_api/test_data_workflows.py +++ b/tests/tests_integration/test_api/test_data_workflows.py @@ -18,7 +18,7 @@ WorkflowScheduledTriggerRule, WorkflowTask, WorkflowTrigger, - WorkflowTriggerCreate, + WorkflowTriggerUpsert, WorkflowUpsert, WorkflowVersion, WorkflowVersionList, @@ -252,7 +252,7 @@ def clean_created_workflow_triggers(cognite_client: CogniteClient) -> None: @pytest.fixture() def workflow_scheduled_trigger(cognite_client: CogniteClient, add_multiply_workflow: WorkflowVersion) -> None: trigger = cognite_client.workflows.triggers.create( - WorkflowTriggerCreate( + WorkflowTriggerUpsert( external_id="integration_test-workflow-scheduled-trigger", trigger_rule=WorkflowScheduledTriggerRule(cron_expression="* * * * *"), workflow_external_id="integration_test-workflow-add_multiply", @@ -486,7 +486,7 @@ def test_trigger_cancel_retry_workflow( class TestWorkflowTriggers: @pytest.mark.usefixtures("clean_created_sessions", "clean_created_workflow_triggers") - def test_create_delete( + def test_create_update_delete( self, cognite_client: CogniteClient, workflow_scheduled_trigger: WorkflowTrigger, @@ -500,6 +500,24 @@ def test_create_delete( assert workflow_scheduled_trigger.created_time is not None assert workflow_scheduled_trigger.last_updated_time is not None + updated_trigger = cognite_client.workflows.triggers.upsert( + WorkflowTriggerUpsert( + external_id=workflow_scheduled_trigger.external_id, + trigger_rule=WorkflowScheduledTriggerRule(cron_expression="0 * * * *"), + workflow_external_id=workflow_scheduled_trigger.workflow_external_id, + workflow_version=workflow_scheduled_trigger.workflow_version, + input=workflow_scheduled_trigger.input, + ) + ) + assert updated_trigger is not None + assert updated_trigger.external_id == workflow_scheduled_trigger.external_id + assert updated_trigger.trigger_rule == WorkflowScheduledTriggerRule(cron_expression="0 * * * *") + assert updated_trigger.workflow_external_id == workflow_scheduled_trigger.workflow_external_id + assert updated_trigger.workflow_version == workflow_scheduled_trigger.workflow_version + assert updated_trigger.input == workflow_scheduled_trigger.input + assert updated_trigger.created_time == workflow_scheduled_trigger.created_time + assert updated_trigger.last_updated_time > workflow_scheduled_trigger.last_updated_time + @pytest.mark.usefixtures("clean_created_sessions", "clean_created_workflow_triggers") def test_trigger_list( self,