Skip to content

Commit 70dde8f

Browse files
committed
Deprecate PEWs.
Attach a deprecation warning to the PEW and PEW Execution collections and their associated operations. The associated response objects (PredictorEvaluationWorkflow and PredictorEvaluationExecution) are also deprecated, but as they're only produced by the collections, their docstring notes their deprecation rather than an emitted message, to avoid inundating the user.
1 parent 05c1af2 commit 70dde8f

13 files changed

+166
-88
lines changed

src/citrine/informatics/executions/predictor_evaluation_execution.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99

1010
class PredictorEvaluationExecution(Resource['PredictorEvaluationExecution'], Execution):
11-
"""The execution of a PredictorEvaluationWorkflow.
11+
"""[DEPRECATED] The execution of a PredictorEvaluationWorkflow.
1212
1313
Possible statuses are INPROGRESS, SUCCEEDED, and FAILED.
1414
Predictor evaluation executions also have a ``status_description`` field with more information.

src/citrine/informatics/workflows/predictor_evaluation_workflow.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
class PredictorEvaluationWorkflow(Resource['PredictorEvaluationWorkflow'],
1414
Workflow, AIResourceMetadata):
15-
"""A workflow that evaluations a predictor.
15+
"""[DEPRECATED] A workflow that evaluates a predictor.
1616
1717
Parameters
1818
----------

src/citrine/resources/predictor_evaluation_execution.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""Resources that represent both individual and collections of predictor evaluation executions."""
2+
from deprecation import deprecated
23
from functools import partial
34
from typing import Optional, Union, Iterator
45
from uuid import UUID
@@ -19,6 +20,9 @@ class PredictorEvaluationExecutionCollection(Collection["PredictorEvaluationExec
1920
_collection_key = 'response'
2021
_resource = predictor_evaluation_execution.PredictorEvaluationExecution
2122

23+
@deprecated(deprecated_in="3.23.0", removed_in="4.0.0",
24+
details="Predictor evaluation workflows are being eliminated in favor of directly"
25+
"evaluating predictors. Please use Project.predictor_evaluations instead.")
2226
def __init__(self,
2327
project_id: UUID,
2428
session: Session,
@@ -34,6 +38,8 @@ def build(self, data: dict) -> predictor_evaluation_execution.PredictorEvaluatio
3438
execution.project_id = self.project_id
3539
return execution
3640

41+
@deprecated(deprecated_in="3.23.0", removed_in="4.0.0",
42+
details="Please use PredictorEvaluationCollection.trigger instead.")
3743
def trigger(self,
3844
predictor_id: UUID,
3945
*,
@@ -71,18 +77,22 @@ def trigger(self,
7177

7278
return self.build(data)
7379

80+
@deprecated(deprecated_in="3.23.0", removed_in="4.0.0")
7481
def register(self,
7582
model: predictor_evaluation_execution.PredictorEvaluationExecution
7683
) -> predictor_evaluation_execution.PredictorEvaluationExecution:
7784
"""Cannot register an execution."""
7885
raise NotImplementedError("Cannot register a PredictorEvaluationExecution.")
7986

87+
@deprecated(deprecated_in="3.23.0", removed_in="4.0.0")
8088
def update(self,
8189
model: predictor_evaluation_execution.PredictorEvaluationExecution
8290
) -> predictor_evaluation_execution.PredictorEvaluationExecution:
8391
"""Cannot update an execution."""
8492
raise NotImplementedError("Cannot update a PredictorEvaluationExecution.")
8593

94+
@deprecated(deprecated_in="3.23.0", removed_in="4.0.0",
95+
details="Please use PredictorEvaluation.archive")
8696
def archive(self, uid: Union[UUID, str]):
8797
"""Archive a predictor evaluation execution.
8898
@@ -94,6 +104,8 @@ def archive(self, uid: Union[UUID, str]):
94104
"""
95105
self._put_resource_ref('archive', uid)
96106

107+
@deprecated(deprecated_in="3.23.0", removed_in="4.0.0",
108+
details="Please use PredictorEvaluation.restore")
97109
def restore(self, uid: Union[UUID, str]):
98110
"""Restore an archived predictor evaluation execution.
99111
@@ -105,6 +117,8 @@ def restore(self, uid: Union[UUID, str]):
105117
"""
106118
self._put_resource_ref('restore', uid)
107119

120+
@deprecated(deprecated_in="3.23.0", removed_in="4.0.0",
121+
details="Please use PredictorEvaluation.list")
108122
def list(self,
109123
*,
110124
per_page: int = 100,
@@ -144,7 +158,15 @@ def list(self,
144158
collection_builder=self._build_collection_elements,
145159
per_page=per_page)
146160

161+
@deprecated(deprecated_in="3.23.0", removed_in="4.0.0")
147162
def delete(self, uid: Union[UUID, str]) -> Response:
148163
"""Predictor Evaluation Executions cannot be deleted; they can be archived instead."""
149164
raise NotImplementedError(
150165
"Predictor Evaluation Executions cannot be deleted; they can be archived instead.")
166+
167+
@deprecated(deprecated_in="3.23.0", removed_in="4.0.0",
168+
details="Please use PredictorEvaluation.get")
169+
def get(self,
170+
uid: Union[UUID, str]) -> predictor_evaluation_execution.PredictorEvaluationExecution:
171+
"""Get a particular element of the collection."""
172+
return super().get(uid)

src/citrine/resources/predictor_evaluation_workflow.py

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"""Resources that represent both individual and collections of workflow executions."""
2-
from typing import Optional, Union
2+
from deprecation import deprecated
3+
from typing import Iterator, Optional, Union
34
from uuid import UUID
45

56
from citrine._rest.collection import Collection
@@ -16,6 +17,9 @@ class PredictorEvaluationWorkflowCollection(Collection[PredictorEvaluationWorkfl
1617
_collection_key = 'response'
1718
_resource = PredictorEvaluationWorkflow
1819

20+
@deprecated(deprecated_in="3.23.0", removed_in="4.0.0",
21+
details="Predictor evaluation workflows are being eliminated in favor of directly"
22+
"evaluating predictors. Please use Project.predictor_evaluations instead.")
1923
def __init__(self, project_id: UUID, session: Session):
2024
self.project_id: UUID = project_id
2125
self.session: Session = session
@@ -27,6 +31,8 @@ def build(self, data: dict) -> PredictorEvaluationWorkflow:
2731
workflow.project_id = self.project_id
2832
return workflow
2933

34+
@deprecated(deprecated_in="3.23.0", removed_in="4.0.0",
35+
details="Please use PredictorEvaluations instead, which doesn't store workflows.")
3036
def archive(self, uid: Union[UUID, str]):
3137
"""Archive a predictor evaluation workflow.
3238
@@ -38,6 +44,8 @@ def archive(self, uid: Union[UUID, str]):
3844
"""
3945
return self._put_resource_ref('archive', uid)
4046

47+
@deprecated(deprecated_in="3.23.0", removed_in="4.0.0",
48+
details="Please use PredictorEvaluations instead, which doesn't store workflows.")
4149
def restore(self, uid: Union[UUID, str] = None):
4250
"""Restore an archived predictor evaluation workflow.
4351
@@ -49,11 +57,15 @@ def restore(self, uid: Union[UUID, str] = None):
4957
"""
5058
return self._put_resource_ref('restore', uid)
5159

60+
@deprecated(deprecated_in="3.23.0", removed_in="4.0.0")
5261
def delete(self, uid: Union[UUID, str]) -> Response:
5362
"""Predictor Evaluation Workflows cannot be deleted; they can be archived instead."""
5463
raise NotImplementedError(
5564
"Predictor Evaluation Workflows cannot be deleted; they can be archived instead.")
5665

66+
@deprecated(deprecated_in="3.23.0", removed_in="4.0.0",
67+
details="Please use PredictorEvaluations.trigger_default instead. It doesn't store"
68+
" a workflow, but it triggers an evaluation with the default evaluators.")
5769
def create_default(self,
5870
*,
5971
predictor_id: UUID,
@@ -95,3 +107,27 @@ def create_default(self,
95107
payload['predictor_version'] = predictor_version
96108
data = self.session.post_resource(url, payload)
97109
return self.build(data)
110+
111+
@deprecated(deprecated_in="3.23.0", removed_in="4.0.0",
112+
details="Please use PredictorEvaluations instead, which doesn't store workflows.")
113+
def register(self, model: PredictorEvaluationWorkflow) -> PredictorEvaluationWorkflow:
114+
"""Create a new element of the collection by registering an existing resource."""
115+
return super().register(model)
116+
117+
@deprecated(deprecated_in="3.23.0", removed_in="4.0.0",
118+
details="Please use PredictorEvaluations instead, which doesn't store workflows.")
119+
def list(self, *, per_page: int = 100) -> Iterator[PredictorEvaluationWorkflow]:
120+
"""Paginate over the elements of the collection."""
121+
return super().list(per_page=per_page)
122+
123+
@deprecated(deprecated_in="3.23.0", removed_in="4.0.0",
124+
details="Please use PredictorEvaluations instead, which doesn't store workflows.")
125+
def update(self, model: PredictorEvaluationWorkflow) -> PredictorEvaluationWorkflow:
126+
"""Update a particular element of the collection."""
127+
return super().update(model)
128+
129+
@deprecated(deprecated_in="3.23.0", removed_in="4.0.0",
130+
details="Please use PredictorEvaluations instead, which doesn't store workflows.")
131+
def get(self, uid: Union[UUID, str]) -> PredictorEvaluationWorkflow:
132+
"""Get a particular element of the collection."""
133+
return super().get(uid)

tests/informatics/workflows/test_predictor_evaluation_workflow.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,5 @@ def test_execution_error(pew):
3636
pew.executions
3737

3838
pew.project_id = "foo"
39-
assert pew.executions.project_id == "foo"
39+
with pytest.deprecated_call():
40+
assert pew.executions.project_id == "foo"

tests/resources/test_predictor_evaluation_executions.py

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@ def session() -> FakeSession:
1717

1818
@pytest.fixture
1919
def collection(session) -> PredictorEvaluationExecutionCollection:
20-
return PredictorEvaluationExecutionCollection(
21-
project_id=uuid.uuid4(),
22-
workflow_id=uuid.uuid4(),
23-
session=session,
24-
)
20+
with pytest.deprecated_call():
21+
return PredictorEvaluationExecutionCollection(
22+
project_id=uuid.uuid4(),
23+
workflow_id=uuid.uuid4(),
24+
session=session,
25+
)
2526

2627

2728
@pytest.fixture
@@ -37,11 +38,13 @@ def test_basic_methods(workflow_execution, collection):
3738

3839
assert "Example evaluator" in list(iter(workflow_execution))
3940

40-
with pytest.raises(NotImplementedError):
41-
collection.register(workflow_execution)
41+
with pytest.deprecated_call():
42+
with pytest.raises(NotImplementedError):
43+
collection.register(workflow_execution)
4244

43-
with pytest.raises(NotImplementedError):
44-
collection.update(workflow_execution)
45+
with pytest.deprecated_call():
46+
with pytest.raises(NotImplementedError):
47+
collection.update(workflow_execution)
4548

4649

4750
def test_build_new_execution(collection, predictor_evaluation_execution_dict):
@@ -87,7 +90,8 @@ def test_trigger_workflow_execution(collection: PredictorEvaluationExecutionColl
8790
session.set_response(predictor_evaluation_execution_dict)
8891

8992
# When
90-
actual_execution = collection.trigger(predictor_id, random_state=random_state)
93+
with pytest.deprecated_call():
94+
actual_execution = collection.trigger(predictor_id, random_state=random_state)
9195

9296
# Then
9397
assert str(actual_execution.uid) == predictor_evaluation_execution_dict["id"]
@@ -110,7 +114,8 @@ def test_trigger_workflow_execution_with_version(collection: PredictorEvaluation
110114
session.set_response(predictor_evaluation_execution_dict)
111115

112116
# When
113-
actual_execution = collection.trigger(predictor_id, predictor_version=predictor_version)
117+
with pytest.deprecated_call():
118+
actual_execution = collection.trigger(predictor_id, predictor_version=predictor_version)
114119

115120
# Then
116121
assert str(actual_execution.uid) == predictor_evaluation_execution_dict["id"]
@@ -129,7 +134,8 @@ def test_trigger_workflow_execution_with_version(collection: PredictorEvaluation
129134
def test_list(collection: PredictorEvaluationExecutionCollection, session, predictor_version):
130135
session.set_response({"page": 1, "per_page": 4, "next": "", "response": []})
131136
predictor_id = uuid.uuid4()
132-
lst = list(collection.list(per_page=4, predictor_id=predictor_id, predictor_version=predictor_version))
137+
with pytest.deprecated_call():
138+
lst = list(collection.list(per_page=4, predictor_id=predictor_id, predictor_version=predictor_version))
133139
assert not lst
134140

135141
expected_path = '/projects/{}/predictor-evaluation-executions'.format(collection.project_id)
@@ -140,17 +146,29 @@ def test_list(collection: PredictorEvaluationExecutionCollection, session, predi
140146

141147

142148
def test_archive(workflow_execution, collection):
143-
collection.archive(workflow_execution.uid)
149+
with pytest.deprecated_call():
150+
collection.archive(workflow_execution.uid)
144151
expected_path = '/projects/{}/predictor-evaluation-executions/archive'.format(collection.project_id)
145152
assert collection.session.last_call == FakeCall(method='PUT', path=expected_path, json={"module_uid": str(workflow_execution.uid)})
146153

147154

148155
def test_restore(workflow_execution, collection):
149-
collection.restore(workflow_execution.uid)
156+
with pytest.deprecated_call():
157+
collection.restore(workflow_execution.uid)
150158
expected_path = '/projects/{}/predictor-evaluation-executions/restore'.format(collection.project_id)
151159
assert collection.session.last_call == FakeCall(method='PUT', path=expected_path, json={"module_uid": str(workflow_execution.uid)})
152160

153161

154162
def test_delete(collection):
155-
with pytest.raises(NotImplementedError):
156-
collection.delete(uuid.uuid4())
163+
with pytest.deprecated_call():
164+
with pytest.raises(NotImplementedError):
165+
collection.delete(uuid.uuid4())
166+
167+
def test_get(predictor_evaluation_execution_dict, workflow_execution, collection):
168+
collection.session.set_response(predictor_evaluation_execution_dict)
169+
170+
with pytest.deprecated_call():
171+
execution = collection.get(workflow_execution.uid)
172+
173+
expected_path = f'/projects/{collection.project_id}/predictor-evaluation-executions/{workflow_execution.uid}'
174+
assert collection.session.last_call == FakeCall(method='GET', path=expected_path)

tests/resources/test_predictor_evaluation_workflows.py

Lines changed: 55 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,11 @@ def session() -> FakeSession:
1515

1616
@pytest.fixture
1717
def collection(session) -> PredictorEvaluationWorkflowCollection:
18-
return PredictorEvaluationWorkflowCollection(
19-
project_id=uuid.uuid4(),
20-
session=session,
21-
)
18+
with pytest.deprecated_call():
19+
return PredictorEvaluationWorkflowCollection(
20+
project_id=uuid.uuid4(),
21+
session=session,
22+
)
2223

2324

2425
@pytest.fixture
@@ -33,22 +34,25 @@ def test_basic_methods(workflow, collection):
3334

3435

3536
def test_archive(workflow, collection):
36-
collection.archive(workflow.uid)
37+
with pytest.deprecated_call():
38+
collection.archive(workflow.uid)
3739
expected_path = '/projects/{}/predictor-evaluation-workflows/archive'.format(collection.project_id)
3840
assert collection.session.last_call == FakeCall(method='PUT', path=expected_path,
3941
json={"module_uid": str(workflow.uid)})
4042

4143

4244
def test_restore(workflow, collection):
43-
collection.restore(workflow.uid)
45+
with pytest.deprecated_call():
46+
collection.restore(workflow.uid)
4447
expected_path = '/projects/{}/predictor-evaluation-workflows/restore'.format(collection.project_id)
4548
assert collection.session.last_call == FakeCall(method='PUT', path=expected_path,
4649
json={"module_uid": str(workflow.uid)})
4750

4851

4952
def test_delete(collection):
50-
with pytest.raises(NotImplementedError):
51-
collection.delete(uuid.uuid4())
53+
with pytest.deprecated_call():
54+
with pytest.raises(NotImplementedError):
55+
collection.delete(uuid.uuid4())
5256

5357

5458
@pytest.mark.parametrize("predictor_version", (2, "1", "latest", None))
@@ -60,11 +64,13 @@ def test_create_default(predictor_evaluation_workflow_dict: dict,
6064

6165
session = FakeSession()
6266
session.set_response(predictor_evaluation_workflow_dict)
63-
collection = PredictorEvaluationWorkflowCollection(
64-
project_id=project_id,
65-
session=session
66-
)
67-
default_workflow = collection.create_default(predictor_id=predictor_id, predictor_version=predictor_version)
67+
with pytest.deprecated_call():
68+
collection = PredictorEvaluationWorkflowCollection(
69+
project_id=project_id,
70+
session=session
71+
)
72+
with pytest.deprecated_call():
73+
default_workflow = collection.create_default(predictor_id=predictor_id, predictor_version=predictor_version)
6874

6975
url = f'/projects/{collection.project_id}/predictor-evaluation-workflows/default'
7076

@@ -73,3 +79,39 @@ def test_create_default(predictor_evaluation_workflow_dict: dict,
7379
expected_payload["predictor_version"] = predictor_version
7480
assert session.calls == [FakeCall(method="POST", path=url, json=expected_payload)]
7581
assert default_workflow.dump() == workflow.dump()
82+
83+
def test_register(predictor_evaluation_workflow_dict, workflow, collection):
84+
collection.session.set_response(predictor_evaluation_workflow_dict)
85+
86+
with pytest.deprecated_call():
87+
collection.register(workflow)
88+
89+
expected_path = f'/projects/{collection.project_id}/predictor-evaluation-workflows'
90+
assert collection.session.last_call == FakeCall(method='POST', path=expected_path, json=workflow.dump())
91+
92+
def test_list(predictor_evaluation_workflow_dict, workflow, collection):
93+
collection.session.set_response({"page": 1, "per_page": 4, "next": "", "response": [predictor_evaluation_workflow_dict]})
94+
95+
with pytest.deprecated_call():
96+
list(collection.list(per_page=20))
97+
98+
expected_path = f'/projects/{collection.project_id}/predictor-evaluation-workflows'
99+
assert collection.session.last_call == FakeCall(method='GET', path=expected_path, params={"per_page": 20, "page": 1})
100+
101+
def test_update(predictor_evaluation_workflow_dict, workflow, collection):
102+
collection.session.set_response(predictor_evaluation_workflow_dict)
103+
104+
with pytest.deprecated_call():
105+
collection.update(workflow)
106+
107+
expected_path = f'/projects/{collection.project_id}/predictor-evaluation-workflows/{workflow.uid}'
108+
assert collection.session.last_call == FakeCall(method='PUT', path=expected_path, json=workflow.dump())
109+
110+
def test_get(predictor_evaluation_workflow_dict, workflow, collection):
111+
collection.session.set_response(predictor_evaluation_workflow_dict)
112+
113+
with pytest.deprecated_call():
114+
collection.get(workflow.uid)
115+
116+
expected_path = f'/projects/{collection.project_id}/predictor-evaluation-workflows/{workflow.uid}'
117+
assert collection.session.last_call == FakeCall(method='GET', path=expected_path)

0 commit comments

Comments
 (0)