diff --git a/src/citrine/__version__.py b/src/citrine/__version__.py index 1b052a2ba..0e6cf3e2e 100644 --- a/src/citrine/__version__.py +++ b/src/citrine/__version__.py @@ -1 +1 @@ -__version__ = "3.18.0" +__version__ = "3.19.0" diff --git a/src/citrine/resources/_default_labels.py b/src/citrine/resources/_default_labels.py new file mode 100644 index 000000000..f4ce943ea --- /dev/null +++ b/src/citrine/resources/_default_labels.py @@ -0,0 +1,21 @@ +from typing import List, Optional + +from citrine.resources.data_concepts import CITRINE_TAG_PREFIX + +_CITRINE_DEFAULT_LABEL_PREFIX = f'{CITRINE_TAG_PREFIX}::mat_label' + + +def _inject_default_label_tags( + original_tags: Optional[List[str]], default_labels: Optional[List[str]] +) -> Optional[List[str]]: + if default_labels is None: + all_tags = original_tags + else: + labels_as_tags = [ + f"{_CITRINE_DEFAULT_LABEL_PREFIX}::{label}" for label in default_labels + ] + if original_tags is None: + all_tags = labels_as_tags + else: + all_tags = list(original_tags) + labels_as_tags + return all_tags diff --git a/src/citrine/resources/material_run.py b/src/citrine/resources/material_run.py index 2c404587f..fb2a62cc0 100644 --- a/src/citrine/resources/material_run.py +++ b/src/citrine/resources/material_run.py @@ -6,8 +6,8 @@ from citrine._serialization.properties import Optional as PropertyOptional from citrine._serialization.properties import String, LinkOrElse from citrine._utils.functions import format_escaped_url +from citrine.resources._default_labels import _inject_default_label_tags from citrine.resources.data_concepts import _make_link_by_uid -from citrine.resources.data_concepts import CITRINE_TAG_PREFIX from citrine.resources.material_spec import MaterialSpecCollection from citrine.resources.object_runs import ObjectRun, ObjectRunCollection from gemd.entity.file_link import FileLink @@ -53,8 +53,6 @@ class MaterialRun( default_labels: List[str], optional An optional set of default labels to apply to this material run. Default labels are used to: - - Populate labels on the ingredient run, if none are explicitly - specified, when the material run is later used as an ingredient - Marking the material run as a potential replacement ingredient for a particular label when generating new candidates using a design space. Note that during design, default labels are only applicable @@ -229,22 +227,3 @@ def list_by_template(self, specs = spec_collection.list_by_template(uid=_make_link_by_uid(uid)) return (run for runs in (self.list_by_spec(spec) for spec in specs) for run in runs) - - -_CITRINE_DEFAULT_LABEL_PREFIX = f'{CITRINE_TAG_PREFIX}::mat_label' - - -def _inject_default_label_tags( - original_tags: Optional[List[str]], default_labels: Optional[List[str]] -) -> Optional[List[str]]: - if default_labels is None: - all_tags = original_tags - else: - labels_as_tags = [ - f"{_CITRINE_DEFAULT_LABEL_PREFIX}::{label}" for label in default_labels - ] - if original_tags is None: - all_tags = labels_as_tags - else: - all_tags = list(original_tags) + labels_as_tags - return all_tags diff --git a/src/citrine/resources/material_spec.py b/src/citrine/resources/material_spec.py index b82c1d1d4..9a8654cf9 100644 --- a/src/citrine/resources/material_spec.py +++ b/src/citrine/resources/material_spec.py @@ -6,6 +6,7 @@ from citrine._serialization.properties import List as PropertyList from citrine._serialization.properties import Optional as PropertyOptional from citrine._serialization.properties import String, LinkOrElse, Object +from citrine.resources._default_labels import _inject_default_label_tags from citrine.resources.object_specs import ObjectSpec, ObjectSpecCollection from gemd.entity.attribute.property_and_conditions import PropertyAndConditions from gemd.entity.file_link import FileLink @@ -47,6 +48,11 @@ class MaterialSpec( A template bounding the valid values for this material's properties. file_links: List[FileLink], optional Links to associated files, with resource paths into the files API. + default_labels: List[str], optional + An optional set of default labels to apply to this material spec. + Default labels are used to: + - Populate labels on the ingredient spec, if none are explicitly + specified, when the material spec is later used in an ingredient spec """ @@ -75,12 +81,14 @@ def __init__(self, process: Optional[GEMDProcessSpec] = None, properties: Optional[List[PropertyAndConditions]] = None, template: Optional[GEMDMaterialTemplate] = None, - file_links: Optional[List[FileLink]] = None): + file_links: Optional[List[FileLink]] = None, + default_labels: Optional[List[str]] = None): if uids is None: uids = dict() + all_tags = _inject_default_label_tags(tags, default_labels) super(ObjectSpec, self).__init__() GEMDMaterialSpec.__init__(self, name=name, uids=uids, - tags=tags, process=process, properties=properties, + tags=all_tags, process=process, properties=properties, template=template, file_links=file_links, notes=notes) def __str__(self): diff --git a/tests/resources/test_default_labels.py b/tests/resources/test_default_labels.py new file mode 100644 index 000000000..b6d8267b0 --- /dev/null +++ b/tests/resources/test_default_labels.py @@ -0,0 +1,39 @@ +import pytest + +from citrine.resources._default_labels import _inject_default_label_tags + +@pytest.mark.parametrize( + "original_tags, default_labels, expected", + [ + (None, None, None), + (None, [], []), + ([], None, []), + ([], [], []), + ( + None, + ["label 0", "label 1"], + ["citr_auto::mat_label::label 0", "citr_auto::mat_label::label 1"], + ), + ( + [], + ["label 0", "label 1"], + ["citr_auto::mat_label::label 0", "citr_auto::mat_label::label 1"], + ), + (["alpha", "beta", "gamma"], None, ["alpha", "beta", "gamma"]), + (["alpha", "beta", "gamma"], [], ["alpha", "beta", "gamma"]), + ( + ["alpha", "beta", "gamma"], + ["label 0", "label 1"], + [ + "alpha", + "beta", + "gamma", + "citr_auto::mat_label::label 0", + "citr_auto::mat_label::label 1", + ], + ), + ], +) +def test_inject_default_label_tags(original_tags, default_labels, expected): + result = _inject_default_label_tags(original_tags, default_labels) + assert result == expected diff --git a/tests/resources/test_material_run.py b/tests/resources/test_material_run.py index 3921b3bf1..1c24e4bcd 100644 --- a/tests/resources/test_material_run.py +++ b/tests/resources/test_material_run.py @@ -55,43 +55,6 @@ def test_invalid_collection_construction(): session=session) -@pytest.mark.parametrize( - "original_tags, default_labels, expected", - [ - (None, None, None), - (None, [], []), - ([], None, []), - ([], [], []), - ( - None, - ["label 0", "label 1"], - ["citr_auto::mat_label::label 0", "citr_auto::mat_label::label 1"], - ), - ( - [], - ["label 0", "label 1"], - ["citr_auto::mat_label::label 0", "citr_auto::mat_label::label 1"], - ), - (["alpha", "beta", "gamma"], None, ["alpha", "beta", "gamma"]), - (["alpha", "beta", "gamma"], [], ["alpha", "beta", "gamma"]), - ( - ["alpha", "beta", "gamma"], - ["label 0", "label 1"], - [ - "alpha", - "beta", - "gamma", - "citr_auto::mat_label::label 0", - "citr_auto::mat_label::label 1", - ], - ), - ], -) -def test_inject_default_label_tags(original_tags, default_labels, expected): - result = _inject_default_label_tags(original_tags, default_labels) - assert result == expected - - def test_register_material_run(collection, session): # Given session.set_response(MaterialRunDataFactory(name='Test MR 123'))