Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/citrine/__version__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
__version__ = "3.28.0"
__version__ = "3.29.0"
18 changes: 17 additions & 1 deletion src/citrine/informatics/executions/design_execution.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from citrine._serialization import properties
from citrine._utils.functions import format_escaped_url
from citrine.informatics.descriptors import Descriptor
from citrine.informatics.design_candidate import DesignCandidate
from citrine.informatics.design_candidate import DesignCandidate, HierarchicalDesignCandidate
from citrine.informatics.predict_request import PredictRequest
from citrine.informatics.scores import Score
from citrine.informatics.executions.execution import Execution
Expand Down Expand Up @@ -56,6 +56,22 @@ def candidates(self, *, per_page: int = 100) -> Iterable[DesignCandidate]:
collection_builder=self._build_candidates,
per_page=per_page)

@classmethod
def _build_hierarchical_candidates(
cls, subset_collection: Iterable[dict]) -> Iterable[HierarchicalDesignCandidate]:
for candidate in subset_collection:
yield HierarchicalDesignCandidate.build(candidate)

def hierarchical_candidates(self, *, per_page: int = 100) -> Iterable[DesignCandidate]:
"""Fetch the Design Candidates for the particular execution, paginated."""
path = self._path() + '/candidate-histories'

fetcher = partial(self._fetch_page, path=path, fetch_func=self._session.get_resource)

return self._paginator.paginate(page_fetcher=fetcher,
collection_builder=self._build_hierarchical_candidates,
per_page=per_page)

def predict(self,
predict_request: PredictRequest) -> DesignCandidate:
"""Invoke a prediction on a design candidate."""
Expand Down
24 changes: 24 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -839,6 +839,30 @@ def example_hierarchical_design_material(example_design_material):
}


@pytest.fixture()
def example_hierarchical_candidates(example_hierarchical_design_material):
return {
"page": 2,
"per_page": 4,
"response": [{
"id": str(uuid.uuid4()),
"primary_score": 0,
"rank": 1,
"material": example_hierarchical_design_material,
"name": "Example candidate",
"hidden": True,
"comments": [
{
"message": "a message",
"created": {
"user": str(uuid.uuid4()),
"time": '2025-02-20T10:46:26Z'
}
}
]
}]
}

@pytest.fixture()
def example_candidates(example_design_material):
return {
Expand Down
16 changes: 16 additions & 0 deletions tests/resources/test_design_executions.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,22 @@ def test_workflow_execution_results(workflow_execution: DesignExecution, session
assert session.last_call == FakeCall(method='GET', path=expected_path, params={"per_page": 4, 'page': 1})


def test_workflow_execution_hierarchical_results(workflow_execution: DesignExecution, session, example_hierarchical_candidates):
# Given
session.set_response(example_hierarchical_candidates)

# When
list(workflow_execution.hierarchical_candidates(per_page=4))

# Then
expected_path = '/projects/{}/design-workflows/{}/executions/{}/candidate-histories'.format(
workflow_execution.project_id,
workflow_execution.workflow_id,
workflow_execution.uid,
)
assert session.last_call == FakeCall(method='GET', path=expected_path, params={"per_page": 4, 'page': 1})


def test_workflow_execution_results_pinned(workflow_execution: DesignExecution, session, example_candidates):
# Given
pinned_by = uuid.uuid4()
Expand Down
Loading