Skip to content

Commit 470275e

Browse files
committed
[PNE-7751] Expose hierarchical candidates.
Hierarchical candidates are produced by multi-step search spaces.
1 parent 1ff0c99 commit 470275e

File tree

4 files changed

+58
-2
lines changed

4 files changed

+58
-2
lines changed

src/citrine/__version__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "3.28.0"
1+
__version__ = "3.29.0"

src/citrine/informatics/executions/design_execution.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from citrine._serialization import properties
77
from citrine._utils.functions import format_escaped_url
88
from citrine.informatics.descriptors import Descriptor
9-
from citrine.informatics.design_candidate import DesignCandidate
9+
from citrine.informatics.design_candidate import DesignCandidate, HierarchicalDesignCandidate
1010
from citrine.informatics.predict_request import PredictRequest
1111
from citrine.informatics.scores import Score
1212
from citrine.informatics.executions.execution import Execution
@@ -56,6 +56,22 @@ def candidates(self, *, per_page: int = 100) -> Iterable[DesignCandidate]:
5656
collection_builder=self._build_candidates,
5757
per_page=per_page)
5858

59+
@classmethod
60+
def _build_hierarchical_candidates(
61+
cls, subset_collection: Iterable[dict]) -> Iterable[HierarchicalDesignCandidate]:
62+
for candidate in subset_collection:
63+
yield HierarchicalDesignCandidate.build(candidate)
64+
65+
def hierarchical_candidates(self, *, per_page: int = 100) -> Iterable[DesignCandidate]:
66+
"""Fetch the Design Candidates for the particular execution, paginated."""
67+
path = self._path() + '/candidate-histories'
68+
69+
fetcher = partial(self._fetch_page, path=path, fetch_func=self._session.get_resource)
70+
71+
return self._paginator.paginate(page_fetcher=fetcher,
72+
collection_builder=self._build_hierarchical_candidates,
73+
per_page=per_page)
74+
5975
def predict(self,
6076
predict_request: PredictRequest) -> DesignCandidate:
6177
"""Invoke a prediction on a design candidate."""

tests/conftest.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -839,6 +839,30 @@ def example_hierarchical_design_material(example_design_material):
839839
}
840840

841841

842+
@pytest.fixture()
843+
def example_hierarchical_candidates(example_hierarchical_design_material):
844+
return {
845+
"page": 2,
846+
"per_page": 4,
847+
"response": [{
848+
"id": str(uuid.uuid4()),
849+
"primary_score": 0,
850+
"rank": 1,
851+
"material": example_hierarchical_design_material,
852+
"name": "Example candidate",
853+
"hidden": True,
854+
"comments": [
855+
{
856+
"message": "a message",
857+
"created": {
858+
"user": str(uuid.uuid4()),
859+
"time": '2025-02-20T10:46:26Z'
860+
}
861+
}
862+
]
863+
}]
864+
}
865+
842866
@pytest.fixture()
843867
def example_candidates(example_design_material):
844868
return {

tests/resources/test_design_executions.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,22 @@ def test_workflow_execution_results(workflow_execution: DesignExecution, session
101101
assert session.last_call == FakeCall(method='GET', path=expected_path, params={"per_page": 4, 'page': 1})
102102

103103

104+
def test_workflow_execution_hierarchical_results(workflow_execution: DesignExecution, session, example_hierarchical_candidates):
105+
# Given
106+
session.set_response(example_hierarchical_candidates)
107+
108+
# When
109+
list(workflow_execution.hierarchical_candidates(per_page=4))
110+
111+
# Then
112+
expected_path = '/projects/{}/design-workflows/{}/executions/{}/candidate-histories'.format(
113+
workflow_execution.project_id,
114+
workflow_execution.workflow_id,
115+
workflow_execution.uid,
116+
)
117+
assert session.last_call == FakeCall(method='GET', path=expected_path, params={"per_page": 4, 'page': 1})
118+
119+
104120
def test_workflow_execution_results_pinned(workflow_execution: DesignExecution, session, example_candidates):
105121
# Given
106122
pinned_by = uuid.uuid4()

0 commit comments

Comments
 (0)