diff --git a/src/citrine/_rest/collection.py b/src/citrine/_rest/collection.py index 6f83805ed..a5a9869a5 100644 --- a/src/citrine/_rest/collection.py +++ b/src/citrine/_rest/collection.py @@ -4,7 +4,7 @@ from citrine._rest.pageable import Pageable from citrine._rest.paginator import Paginator -from citrine._rest.resource import Resource, ResourceRef +from citrine._rest.resource import Resource from citrine._utils.functions import resource_path from citrine.exceptions import ModuleRegistrationFailedException, NonRetryableException from citrine.resources.response import Response @@ -28,11 +28,6 @@ class Collection(Generic[ResourceType], Pageable): _paginator: Paginator = Paginator() _api_version: str = "v1" - def _put_resource_ref(self, subpath: str, uid: Union[UUID, str]): - url = self._get_path(subpath) - ref = ResourceRef(uid) - return self.session.put_resource(url, ref.dump(), version=self._api_version) - def _get_path(self, uid: Optional[Union[UUID, str]] = None, *, diff --git a/src/citrine/_rest/resource.py b/src/citrine/_rest/resource.py index 6bc63d202..a0c1f492d 100644 --- a/src/citrine/_rest/resource.py +++ b/src/citrine/_rest/resource.py @@ -91,16 +91,6 @@ def as_dict(self) -> dict: return result -class ResourceRef(Serializable['ResourceRef']): - """A reference to a resource by UID.""" - - # json key 'module_uid' is a legacy of when this object was only used for modules - uid = properties.UUID('module_uid') - - def __init__(self, uid: Union[UUID, str]): - self.uid = uid - - class PredictorRef(Serializable['PredictorRef']): """A reference to a resource by UID.""" diff --git a/src/citrine/_utils/functions.py b/src/citrine/_utils/functions.py index a2c6c3a2a..e22826cf9 100644 --- a/src/citrine/_utils/functions.py +++ b/src/citrine/_utils/functions.py @@ -319,25 +319,3 @@ def resource_path(*, new_url = base._replace(path='/'.join(path), query=query).geturl() return format_escaped_url(new_url, *action, **kwargs, uid=uid) - - -def _data_manager_deprecation_checks(session, project_id: UUID, team_id: UUID, obj_type: str): - if team_id is None: - if project_id is None: - raise TypeError("Missing one required argument: team_id.") - - warn(f"{obj_type} now belong to Teams, so the project_id parameter was deprecated in " - "3.4.0, and will be removed in 4.0. Please provide the team_id instead.", - DeprecationWarning) - # avoiding a circular import - from citrine.resources.project import Project - team_id = Project.get_team_id_from_project_id(session=session, project_id=project_id) - return team_id - - -def _pad_positional_args(args, n): - if len(args) > 0: - warn("Positional arguments are deprecated and will be removed in v4.0. Please use keyword " - "arguments instead.", - DeprecationWarning) - return args + (None, ) * (n - len(args)) diff --git a/src/citrine/informatics/constraints/ingredient_ratio_constraint.py b/src/citrine/informatics/constraints/ingredient_ratio_constraint.py index f85364ce1..8977470ed 100644 --- a/src/citrine/informatics/constraints/ingredient_ratio_constraint.py +++ b/src/citrine/informatics/constraints/ingredient_ratio_constraint.py @@ -1,4 +1,3 @@ -import warnings from typing import Set, Optional, Tuple from citrine._serialization import properties @@ -106,21 +105,6 @@ def basis_ingredients(self, value: Set[str]): """Set the ingredients in the denominator of the ratio.""" self._basis_ingredients = dict.fromkeys(value, 1) - @property - def basis_ingredient_names(self) -> Set[str]: - """Retrieve the names of all ingredients in the denominator of the ratio.""" - warnings.warn("basis_ingredient_names is deprecated as of 3.0.0 and will be dropped in " - "4.0. Please use basis_ingredients instead.", DeprecationWarning) - return self.basis_ingredients - - # This is for symmetry; it's not strictly necessary. - @basis_ingredient_names.setter - def basis_ingredient_names(self, value: Set[str]): - """Set the names of all ingredients in the denominator of the ratio.""" - warnings.warn("basis_ingredient_names is deprecated as of 3.0.0 and will be dropped in " - "4.0. Please use basis_ingredients instead.", DeprecationWarning) - self.basis_ingredients = value - @property def basis_labels(self) -> Set[str]: """Retrieve the labels in the denominator of the ratio.""" @@ -131,21 +115,6 @@ def basis_labels(self, value: Set[str]): """Set the labels in the denominator of the ratio.""" self._basis_labels = dict.fromkeys(value, 1) - @property - def basis_label_names(self) -> Set[str]: - """Retrieve the names of all labels in the denominator of the ratio.""" - warnings.warn("basis_label_names is deprecated as of 3.0.0 and will be dropped in 4.0. " - "Please use basis_labels instead.", DeprecationWarning) - return self.basis_labels - - # This is for symmetry; it's not strictly necessary. - @basis_label_names.setter - def basis_label_names(self, value: Set[str]): - """Set the names of all labels in the denominator of the ratio.""" - warnings.warn("basis_label_names is deprecated as of 3.0.0 and will be dropped in 4.0. " - "Please use basis_labels instead.", DeprecationWarning) - self.basis_labels = value - def _numerator_read(self, num_dict): if num_dict: return tuple(num_dict.items())[0] diff --git a/src/citrine/informatics/design_spaces/enumerated_design_space.py b/src/citrine/informatics/design_spaces/enumerated_design_space.py index 5b5115cfa..0431b69a6 100644 --- a/src/citrine/informatics/design_spaces/enumerated_design_space.py +++ b/src/citrine/informatics/design_spaces/enumerated_design_space.py @@ -1,5 +1,4 @@ from typing import List, Mapping, Union -from warnings import warn from citrine._rest.engine_resource import EngineResource from citrine._serialization import properties @@ -59,11 +58,5 @@ def data(self) -> List[Mapping[str, Union[int, float, str]]]: return self._data @data.setter - def data(self, value: List[Mapping[str, Union[int, float, str]]]): - for item in value: - for el in item.values(): - if isinstance(el, (int, float)): - warn("Providing numeric data values is deprecated as of 3.4.7, and will be " - "dropped in 4.0.0. Please use strings instead.", - DeprecationWarning) + def data(self, value: List[Mapping[str, str]]): self._data = value diff --git a/src/citrine/informatics/executions/__init__.py b/src/citrine/informatics/executions/__init__.py index aa99edff0..29d83ef89 100644 --- a/src/citrine/informatics/executions/__init__.py +++ b/src/citrine/informatics/executions/__init__.py @@ -1,4 +1,4 @@ # flake8: noqa -from .predictor_evaluation_execution import * +from .predictor_evaluation import * from .design_execution import * from .generative_design_execution import * diff --git a/src/citrine/informatics/executions/predictor_evaluation_execution.py b/src/citrine/informatics/executions/predictor_evaluation_execution.py deleted file mode 100644 index 42a2cdb4e..000000000 --- a/src/citrine/informatics/executions/predictor_evaluation_execution.py +++ /dev/null @@ -1,60 +0,0 @@ -from functools import lru_cache - -from citrine._serialization import properties -from citrine._utils.functions import format_escaped_url -from citrine.informatics.predictor_evaluation_result import PredictorEvaluationResult -from citrine.informatics.executions.execution import Execution -from citrine._rest.resource import Resource - - -class PredictorEvaluationExecution(Resource['PredictorEvaluationExecution'], Execution): - """[DEPRECATED] The execution of a PredictorEvaluationWorkflow. - - Possible statuses are INPROGRESS, SUCCEEDED, and FAILED. - Predictor evaluation executions also have a ``status_description`` field with more information. - - """ - - evaluator_names = properties.List(properties.String, "evaluator_names", serializable=False) - """:List[str]: names of the predictor evaluators that were executed. These are used - when calling the ``results()`` method.""" - workflow_id = properties.UUID('workflow_id', serializable=False) - """:UUID: Unique identifier of the workflow that was executed""" - predictor_id = properties.UUID('predictor_id', serializable=False) - predictor_version = properties.Integer('predictor_version', serializable=False) - - def _path(self): - return format_escaped_url( - '/projects/{project_id}/predictor-evaluation-executions/{execution_id}', - project_id=self.project_id, - execution_id=self.uid - ) - - @lru_cache() - def results(self, evaluator_name: str) -> PredictorEvaluationResult: - """ - Get a specific evaluation result by the name of the evaluator that produced it. - - Parameters - ---------- - evaluator_name: str - Name of the evaluator for which to get the results - - Returns - ------- - PredictorEvaluationResult - The evaluation result from the evaluator with the given name - - """ - params = {"evaluator_name": evaluator_name} - resource = self._session.get_resource(self._path() + "/results", params=params) - return PredictorEvaluationResult.build(resource) - - def __getitem__(self, item): - if isinstance(item, str): - return self.results(item) - else: - raise TypeError("Results are accessed by string names") - - def __iter__(self): - return iter(self.evaluator_names) diff --git a/src/citrine/informatics/predictors/auto_ml_predictor.py b/src/citrine/informatics/predictors/auto_ml_predictor.py index 54874fcd9..db7b0ae8d 100644 --- a/src/citrine/informatics/predictors/auto_ml_predictor.py +++ b/src/citrine/informatics/predictors/auto_ml_predictor.py @@ -1,11 +1,9 @@ from typing import List, Optional, Set -from deprecation import deprecated from gemd.enumeration.base_enumeration import BaseEnumeration from citrine._rest.resource import Resource from citrine._serialization import properties as _properties -from citrine.informatics.data_sources import DataSource from citrine.informatics.descriptors import Descriptor from citrine.informatics.predictors import PredictorNode @@ -52,13 +50,6 @@ class AutoMLPredictor(Resource["AutoMLPredictor"], PredictorNode): estimators: Optional[Set[AutoMLEstimator]] Set of estimators to consider during during AutoML model selection. If None is provided, defaults to AutoMLEstimator.RANDOM_FOREST. - training_data: Optional[List[DataSource]] (deprecated) - Sources of training data. Each can be either a CSV or an GEM Table. Candidates from - multiple data sources will be combined into a flattened list and de-duplicated by uid and - identifiers. De-duplication is performed if a uid or identifier is shared between two or - more rows. The content of a de-duplicated row will contain the union of data across all - rows that share the same uid or at least 1 identifier. Training data is unnecessary if the - predictor is part of a graph that includes all training data required by this predictor. """ @@ -69,11 +60,6 @@ class AutoMLPredictor(Resource["AutoMLPredictor"], PredictorNode): 'estimators', default={AutoMLEstimator.RANDOM_FOREST} ) - _training_data = _properties.List( - _properties.Object(DataSource), - 'training_data', - default=[] - ) typ = _properties.String('type', default='AutoML', deserializable=False) @@ -83,29 +69,12 @@ def __init__(self, description: str, outputs: List[Descriptor], inputs: List[Descriptor], - estimators: Optional[Set[AutoMLEstimator]] = None, - training_data: Optional[List[DataSource]] = None): + estimators: Optional[Set[AutoMLEstimator]] = None): self.name: str = name self.description: str = description self.inputs: List[Descriptor] = inputs self.estimators: Set[AutoMLEstimator] = estimators or {AutoMLEstimator.RANDOM_FOREST} self.outputs = outputs - # self.training_data: List[DataSource] = training_data or [] - if training_data: - self.training_data: List[DataSource] = training_data - - @property - @deprecated(deprecated_in="3.5.0", removed_in="4.0.0", - details="Training data must be accessed through the top-level GraphPredictor.'") - def training_data(self): - """[DEPRECATED] Retrieve training data associated with this node.""" - return self._training_data - - @training_data.setter - @deprecated(deprecated_in="3.5.0", removed_in="4.0.0", - details="Training data should only be added to the top-level GraphPredictor.'") - def training_data(self, value): - self._training_data = value def __str__(self): return ''.format(self.name) diff --git a/src/citrine/informatics/predictors/chemical_formula_featurizer.py b/src/citrine/informatics/predictors/chemical_formula_featurizer.py index 45213ab17..b22f93477 100644 --- a/src/citrine/informatics/predictors/chemical_formula_featurizer.py +++ b/src/citrine/informatics/predictors/chemical_formula_featurizer.py @@ -1,4 +1,4 @@ -from typing import List, Optional, Union +from typing import List, Optional from warnings import warn from citrine._rest.resource import Resource @@ -125,16 +125,16 @@ class ChemicalFormulaFeaturizer(Resource["ChemicalFormulaFeaturizer"], Predictor excludes: Optional[List[str]] The list of features to exclude, either by name or by group alias. Default is none. The final set of features generated by the predictor is set(features) - set(excludes). - powers: Optional[List[int]] + powers: Optional[List[float]] The list of powers to use when computing generalized weighted means of element properties. - p=1 corresponds to the ordinary mean, p=2 is the root mean square, etc. + p=1.0 corresponds to the ordinary mean, p=2.0 is the root mean square, etc. """ input_descriptor = properties.Object(ChemicalFormulaDescriptor, 'input') features = properties.List(properties.String, 'features') excludes = properties.List(properties.String, 'excludes', default=[]) - _powers = properties.List(properties.Float, 'powers') + powers = properties.List(properties.Float, 'powers') typ = properties.String('type', default='ChemicalFormulaFeaturizer', deserializable=False) @@ -145,35 +145,21 @@ def __init__(self, input_descriptor: ChemicalFormulaDescriptor, features: Optional[List[str]] = None, excludes: Optional[List[str]] = None, - powers: Optional[List[int]] = None): + powers: Optional[List[float]] = None): self.name = name self.description = description self.input_descriptor = input_descriptor self.features = features if features is not None else ["standard"] self.excludes = excludes if excludes is not None else [] - self.powers = powers if powers is not None else [1] - - @property - def powers(self) -> List[int]: - """The list of powers when computing generalized weighted means of element properties.""" - warn("The type of 'powers' will change to a list of floats in v4.0.0. To retrieve them as " - "floats now, use 'powers_as_float'.") - truncated = [int(p) for p in self._powers] - if truncated != self._powers: - diffs = [f"{x} => {y}" for x, y in zip(self._powers, truncated) if x != y] - warn(f"The following powers were cast to ints: {'; '.join(diffs)}.") - return truncated - - @powers.setter - def powers(self, value: List[Union[int, float]]): - self._powers = value + self.powers = powers if powers is not None else [1.0] @property def powers_as_float(self) -> List[float]: """Powers when computing generalized weighted means of element properties.""" - warn("'powers_as_float' will be deprecated in v4.0.0 for 'powers', and removed in v5.0.0", - PendingDeprecationWarning) - return self._powers + warn("'powers_as_float' is deprecated as of v4.0.0 in favor of 'powers', and will be " + "removed in v5.0.0", + DeprecationWarning) + return self.powers def __str__(self): return ''.format(self.name) diff --git a/src/citrine/informatics/predictors/mean_property_predictor.py b/src/citrine/informatics/predictors/mean_property_predictor.py index c71bb60df..7d8606bc7 100644 --- a/src/citrine/informatics/predictors/mean_property_predictor.py +++ b/src/citrine/informatics/predictors/mean_property_predictor.py @@ -1,10 +1,7 @@ from typing import List, Mapping, Optional, Union -from deprecation import deprecated - from citrine._rest.resource import Resource from citrine._serialization import properties as _properties -from citrine.informatics.data_sources import DataSource from citrine.informatics.descriptors import ( CategoricalDescriptor, FormulationDescriptor, RealDescriptor ) @@ -54,13 +51,6 @@ class MeanPropertyPredictor(Resource["MeanPropertyPredictor"], PredictorNode): will be used to fill in missing values. Any specified defaults will be used in place of the average over the dataset. ``impute_properties`` must be ``True`` if ``default_properties`` are provided. - training_data: Optional[List[DataSource]] - Sources of training data. Each can be either a CSV or an GEM Table. Candidates from - multiple data sources will be combined into a flattened list and de-duplicated by uid and - identifiers. De-duplication is performed if a uid or identifier is shared between two or - more rows. The content of a de-duplicated row will contain the union of data across all - rows that share the same uid or at least 1 identifier. Training data is unnecessary if the - predictor is part of a graph that includes all training data required by this predictor. """ @@ -81,9 +71,6 @@ class MeanPropertyPredictor(Resource["MeanPropertyPredictor"], PredictorNode): ), 'default_properties' ) - _training_data = _properties.List( - _properties.Object(DataSource), 'training_data', default=[] - ) typ = _properties.String('type', default='MeanProperty', deserializable=False) @@ -96,8 +83,7 @@ def __init__(self, p: float, impute_properties: bool, label: Optional[str] = None, - default_properties: Optional[Mapping[str, Union[str, float]]] = None, - training_data: Optional[List[DataSource]] = None): + default_properties: Optional[Mapping[str, Union[str, float]]] = None): self.name: str = name self.description: str = description self.input_descriptor: FormulationDescriptor = input_descriptor @@ -106,22 +92,6 @@ def __init__(self, self.impute_properties: bool = impute_properties self.label: Optional[str] = label self.default_properties: Optional[Mapping[str, Union[str, float]]] = default_properties - # self.training_data: List[DataSource] = training_data or [] - if training_data: - self.training_data: List[DataSource] = training_data def __str__(self): return ''.format(self.name) - - @property - @deprecated(deprecated_in="3.5.0", removed_in="4.0.0", - details="Training data must be accessed through the top-level GraphPredictor.'") - def training_data(self): - """[DEPRECATED] Retrieve training data associated with this node.""" - return self._training_data - - @training_data.setter - @deprecated(deprecated_in="3.5.0", removed_in="4.0.0", - details="Training data should only be added to the top-level GraphPredictor.'") - def training_data(self, value): - self._training_data = value diff --git a/src/citrine/informatics/predictors/simple_mixture_predictor.py b/src/citrine/informatics/predictors/simple_mixture_predictor.py index da2b1fe4b..05bb71f51 100644 --- a/src/citrine/informatics/predictors/simple_mixture_predictor.py +++ b/src/citrine/informatics/predictors/simple_mixture_predictor.py @@ -1,10 +1,5 @@ -from typing import List, Optional - -from deprecation import deprecated - from citrine._rest.resource import Resource from citrine._serialization import properties -from citrine.informatics.data_sources import DataSource from citrine.informatics.descriptors import FormulationDescriptor from citrine.informatics.predictors import PredictorNode @@ -20,29 +15,14 @@ class SimpleMixturePredictor(Resource["SimpleMixturePredictor"], PredictorNode): name of the configuration description: str description of the predictor - training_data: Optional[List[DataSource]] - Sources of training data. Each can be either a CSV or an GEM Table. Candidates from - multiple data sources will be combined into a flattened list and de-duplicated by uid and - identifiers. De-duplication is performed if a uid or identifier is shared between two or - more rows. The content of a de-duplicated row will contain the union of data across all - rows that share the same uid or at least 1 identifier. Training data is unnecessary if the - predictor is part of a graph that includes all training data required by this predictor. """ - _training_data = properties.List(properties.Object(DataSource), 'training_data', default=[]) - typ = properties.String('type', default='SimpleMixture', deserializable=False) - def __init__(self, - name: str, - *, - description: str, - training_data: Optional[List[DataSource]] = None): + def __init__(self, name: str, *, description: str): self.name: str = name self.description: str = description - if training_data: - self.training_data: List[DataSource] = training_data def __str__(self): return ''.format(self.name) @@ -56,16 +36,3 @@ def input_descriptor(self) -> FormulationDescriptor: def output_descriptor(self) -> FormulationDescriptor: """The output formulation descriptor with key 'Flat Formulation'.""" return FormulationDescriptor.flat() - - @property - @deprecated(deprecated_in="3.5.0", removed_in="4.0.0", - details="Training data must be accessed through the top-level GraphPredictor.'") - def training_data(self): - """[DEPRECATED] Retrieve training data associated with this node.""" - return self._training_data - - @training_data.setter - @deprecated(deprecated_in="3.5.0", removed_in="4.0.0", - details="Training data should only be added to the top-level GraphPredictor.'") - def training_data(self, value): - self._training_data = value diff --git a/src/citrine/informatics/workflows/__init__.py b/src/citrine/informatics/workflows/__init__.py index 39d4a2833..bbc458bfc 100644 --- a/src/citrine/informatics/workflows/__init__.py +++ b/src/citrine/informatics/workflows/__init__.py @@ -1,4 +1,3 @@ # flake8: noqa from .design_workflow import * -from .predictor_evaluation_workflow import * from .workflow import * diff --git a/src/citrine/informatics/workflows/predictor_evaluation_workflow.py b/src/citrine/informatics/workflows/predictor_evaluation_workflow.py deleted file mode 100644 index c6af228e4..000000000 --- a/src/citrine/informatics/workflows/predictor_evaluation_workflow.py +++ /dev/null @@ -1,54 +0,0 @@ -from typing import List - -from citrine._rest.resource import Resource, ResourceTypeEnum -from citrine._serialization import properties -from citrine.informatics.predictor_evaluator import PredictorEvaluator -from citrine.informatics.workflows.workflow import Workflow -from citrine.resources.predictor_evaluation_execution import PredictorEvaluationExecutionCollection -from citrine._rest.ai_resource_metadata import AIResourceMetadata - -__all__ = ['PredictorEvaluationWorkflow'] - - -class PredictorEvaluationWorkflow(Resource['PredictorEvaluationWorkflow'], - Workflow, AIResourceMetadata): - """[DEPRECATED] A workflow that evaluates a predictor. - - Parameters - ---------- - name: str - name of the predictor evaluation workflow - description: str - the description of the predictor evaluation workflow - evaluators: List[PredictorEvaluator] - the list of evaluators to apply to the predictor - - """ - - evaluators = properties.List(properties.Object(PredictorEvaluator), "evaluators") - - status_description = properties.String('status_description', serializable=False) - """:str: more detailed description of the workflow's status""" - typ = properties.String('type', default='PredictorEvaluationWorkflow', deserializable=False) - - _resource_type = ResourceTypeEnum.MODULE - - def __init__(self, - name: str, - *, - description: str = "", - evaluators: List[PredictorEvaluator]): - self.name: str = name - self.description: str = description - self.evaluators: List[PredictorEvaluator] = evaluators - - def __str__(self): - return ''.format(self.name) - - @property - def executions(self) -> PredictorEvaluationExecutionCollection: - """Return a resource representing all visible executions of this workflow.""" - if getattr(self, 'project_id', None) is None: - raise AttributeError('Cannot initialize execution without project reference!') - return PredictorEvaluationExecutionCollection( - project_id=self.project_id, session=self._session, workflow_id=self.uid) diff --git a/src/citrine/jobs/waiting.py b/src/citrine/jobs/waiting.py index 62207947a..78359f438 100644 --- a/src/citrine/jobs/waiting.py +++ b/src/citrine/jobs/waiting.py @@ -7,7 +7,7 @@ from citrine.informatics.executions.design_execution import DesignExecution from citrine.informatics.executions.generative_design_execution import GenerativeDesignExecution from citrine.informatics.executions.sample_design_space_execution import SampleDesignSpaceExecution -from citrine.informatics.executions import PredictorEvaluationExecution +from citrine.informatics.executions import PredictorEvaluation class ConditionTimeoutError(RuntimeError): @@ -130,13 +130,13 @@ def wait_while_validating( def wait_while_executing( *, collection: Union[ - Collection[PredictorEvaluationExecution], + Collection[PredictorEvaluation], Collection[DesignExecution], Collection[GenerativeDesignExecution], Collection[SampleDesignSpaceExecution] ], execution: Union[ - PredictorEvaluationExecution, + PredictorEvaluation, DesignExecution, GenerativeDesignExecution, SampleDesignSpaceExecution @@ -145,7 +145,7 @@ def wait_while_executing( timeout: float = 1800.0, interval: float = 3.0, ) -> Union[ - PredictorEvaluationExecution, + PredictorEvaluation, DesignExecution, GenerativeDesignExecution, SampleDesignSpaceExecution, @@ -155,7 +155,8 @@ def wait_while_executing( Parameters ---------- - execution : Union[PredictorEvaluationExecution, DesignExecution] + execution : Union[PredictorEvaluation, DesignExecution, GenerativeDesignExecution, + SampleDesignSpaceExecution] an execution to monitor print_status_info : bool, optional Whether to print status info, by default False @@ -163,12 +164,16 @@ def wait_while_executing( Maximum time spent inquiring in seconds, by default 1800.0 interval : float, optional Inquiry interval in seconds, by default 3.0 - collection : Union[Collection[PredictorEvaluationExecution], Collection[DesignExecution]] + collection : Union[Collection[PredictorEvaluationExecution], + Collection[DesignExecution], + Collection[GenerativeDesignExecution], + Collection[SampleDesignSpaceExecution]] Collection containing executions Returns ------- - Union[PredictorEvaluationExecution, DesignExecution] + Union[PredictorEvaluationExecution, DesignExecution, GenerativeDesignExecution, + SampleDesignSpaceExecution] the updated execution after it has finished executing diff --git a/src/citrine/resources/data_concepts.py b/src/citrine/resources/data_concepts.py index 344db7ddb..98ff3399b 100644 --- a/src/citrine/resources/data_concepts.py +++ b/src/citrine/resources/data_concepts.py @@ -18,8 +18,7 @@ from citrine._serialization.properties import UUID as PropertyUUID from citrine._serialization.serializable import Serializable from citrine._session import Session -from citrine._utils.functions import _data_manager_deprecation_checks, format_escaped_url, \ - _pad_positional_args, replace_objects_with_links, scrub_none +from citrine._utils.functions import format_escaped_url, replace_objects_with_links, scrub_none from citrine.exceptions import BadRequest from citrine.jobs.job import _poll_for_job_completion from citrine.resources.audit_info import AuditInfo @@ -214,43 +213,27 @@ class DataConceptsCollection(Collection[ResourceType], ABC): """ - def __init__(self, - *args, - session: Session = None, - dataset_id: Optional[UUID] = None, - team_id: UUID = None, - project_id: Optional[UUID] = None): - # Handle positional arguments for backward compatibility - args = _pad_positional_args(args, 3) - self.project_id = project_id or args[0] - self.dataset_id = dataset_id or args[1] - self.session = session or args[2] - if self.session is None: - raise TypeError("Missing one required argument: session.") - - self.team_id = _data_manager_deprecation_checks( - session=self.session, - project_id=self.project_id, - team_id=team_id, - obj_type="GEMD Objects") + def __init__(self, *, session: Session, team_id: UUID, dataset_id: Optional[UUID] = None): + self.dataset_id = dataset_id + self.session = session + self.team_id = team_id @classmethod @abstractmethod def get_type(cls) -> Type[Serializable]: """Return the resource type in the collection.""" + @property + def _path_collection_key(self): + return self._collection_key.replace("_", "-") + @property def _path_template(self): - collection_key = self._collection_key.replace("_", "-") - return f'teams/{self.team_id}/datasets/{self.dataset_id}/{collection_key}' + return f'teams/{self.team_id}/datasets/{self.dataset_id}/{self._path_collection_key}' - # After Data Manager deprecation, both can use the `teams/...` path. @property def _dataset_agnostic_path_template(self): - if self.project_id is None: - return f'teams/{self.team_id}/{self._collection_key.replace("_", "-")}' - else: - return f'projects/{self.project_id}/{self._collection_key.replace("_", "-")}' + return f'teams/{self.team_id}/{self._path_collection_key}' def build(self, data: dict) -> ResourceType: """ diff --git a/src/citrine/resources/dataset.py b/src/citrine/resources/dataset.py index 9d4100b69..99d7c4377 100644 --- a/src/citrine/resources/dataset.py +++ b/src/citrine/resources/dataset.py @@ -5,12 +5,12 @@ from gemd.entity.base_entity import BaseEntity from gemd.entity.link_by_uid import LinkByUID -from citrine._utils.functions import format_escaped_url, _pad_positional_args +from citrine._utils.functions import format_escaped_url from citrine._rest.collection import Collection from citrine._rest.resource import Resource, ResourceTypeEnum from citrine._serialization import properties from citrine._session import Session -from citrine._utils.functions import scrub_none, _data_manager_deprecation_checks +from citrine._utils.functions import scrub_none from citrine.exceptions import NotFound from citrine.resources.api_error import ApiError from citrine.resources.condition_template import ConditionTemplateCollection @@ -80,10 +80,6 @@ class Dataset(Resource['Dataset']): """int: Time the dataset was deleted, in seconds since epoch, if it is deleted.""" public = properties.Optional(properties.Boolean(), 'public') """bool: Flag indicating whether the dataset is publicly readable.""" - project_id = properties.Optional(properties.UUID(), 'project_id', - serializable=False, deserializable=False) - """project_id will be needed here until deprecation is complete. - This class property will be removed post deprecation""" team_id = properties.Optional(properties.UUID(), 'team_id', serializable=False, deserializable=False) session = properties.Optional(properties.Object(Session), 'session', @@ -107,7 +103,6 @@ def __init__(self, name: str, *, summary: Optional[str] = None, self.update_time = None self.delete_time = None self.public = None - self.project_id = None self.team_id = None self.session = None @@ -118,103 +113,101 @@ def __str__(self): def property_templates(self) -> PropertyTemplateCollection: """Return a resource representing all property templates in this dataset.""" return PropertyTemplateCollection(team_id=self.team_id, dataset_id=self.uid, - session=self.session, project_id=self.project_id) + session=self.session) @property def condition_templates(self) -> ConditionTemplateCollection: """Return a resource representing all condition templates in this dataset.""" return ConditionTemplateCollection(team_id=self.team_id, dataset_id=self.uid, - session=self.session, project_id=self.project_id) + session=self.session) @property def parameter_templates(self) -> ParameterTemplateCollection: """Return a resource representing all parameter templates in this dataset.""" return ParameterTemplateCollection(team_id=self.team_id, dataset_id=self.uid, - session=self.session, project_id=self.project_id) + session=self.session) @property def material_templates(self) -> MaterialTemplateCollection: """Return a resource representing all material templates in this dataset.""" return MaterialTemplateCollection(team_id=self.team_id, dataset_id=self.uid, - session=self.session, project_id=self.project_id) + session=self.session) @property def measurement_templates(self) -> MeasurementTemplateCollection: """Return a resource representing all measurement templates in this dataset.""" return MeasurementTemplateCollection(team_id=self.team_id, dataset_id=self.uid, - session=self.session, project_id=self.project_id) + session=self.session) @property def process_templates(self) -> ProcessTemplateCollection: """Return a resource representing all process templates in this dataset.""" return ProcessTemplateCollection(team_id=self.team_id, dataset_id=self.uid, - session=self.session, project_id=self.project_id) + session=self.session) @property def process_runs(self) -> ProcessRunCollection: """Return a resource representing all process runs in this dataset.""" return ProcessRunCollection(team_id=self.team_id, dataset_id=self.uid, - session=self.session, project_id=self.project_id) + session=self.session) @property def measurement_runs(self) -> MeasurementRunCollection: """Return a resource representing all measurement runs in this dataset.""" return MeasurementRunCollection(team_id=self.team_id, dataset_id=self.uid, - session=self.session, project_id=self.project_id) + session=self.session) @property def material_runs(self) -> MaterialRunCollection: """Return a resource representing all material runs in this dataset.""" return MaterialRunCollection(team_id=self.team_id, dataset_id=self.uid, - session=self.session, project_id=self.project_id) + session=self.session) @property def ingredient_runs(self) -> IngredientRunCollection: """Return a resource representing all ingredient runs in this dataset.""" return IngredientRunCollection(team_id=self.team_id, dataset_id=self.uid, - session=self.session, project_id=self.project_id) + session=self.session) @property def process_specs(self) -> ProcessSpecCollection: """Return a resource representing all process specs in this dataset.""" return ProcessSpecCollection(team_id=self.team_id, dataset_id=self.uid, - session=self.session, project_id=self.project_id) + session=self.session) @property def measurement_specs(self) -> MeasurementSpecCollection: """Return a resource representing all measurement specs in this dataset.""" return MeasurementSpecCollection(team_id=self.team_id, dataset_id=self.uid, - session=self.session, project_id=self.project_id) + session=self.session) @property def material_specs(self) -> MaterialSpecCollection: """Return a resource representing all material specs in this dataset.""" return MaterialSpecCollection(team_id=self.team_id, dataset_id=self.uid, - session=self.session, project_id=self.project_id) + session=self.session) @property def ingredient_specs(self) -> IngredientSpecCollection: """Return a resource representing all ingredient specs in this dataset.""" return IngredientSpecCollection(team_id=self.team_id, dataset_id=self.uid, - session=self.session, project_id=self.project_id) + session=self.session) @property def gemd(self) -> GEMDResourceCollection: """Return a resource representing all GEMD objects/templates in this dataset.""" return GEMDResourceCollection(team_id=self.team_id, dataset_id=self.uid, - session=self.session, project_id=self.project_id) + session=self.session) @property def files(self) -> FileCollection: """Return a resource representing all files in the dataset.""" - return FileCollection(team_id=self.team_id, dataset_id=self.uid, - session=self.session, project_id=self.project_id) + return FileCollection(team_id=self.team_id, dataset_id=self.uid, session=self.session) @property def ingestions(self) -> IngestionCollection: """Return a resource representing all files in the dataset.""" - return IngestionCollection(team_id=self.team_id, dataset_id=self.uid, - session=self.session, project_id=self.project_id) + return IngestionCollection(team_id=self.team_id, dataset_id=self.uid, session=self.session) def register(self, model: DataConcepts, *, dry_run=False) -> DataConcepts: """Register a data model object to the appropriate collection.""" @@ -408,7 +401,7 @@ def gemd_batch_delete( class DatasetCollection(Collection[Dataset]): """ - Represents the collection of all datasets associated with a project. + Represents the collection of all datasets associated with a team. Parameters ---------- @@ -422,33 +415,11 @@ class DatasetCollection(Collection[Dataset]): _individual_key = None _collection_key = None _resource = Dataset + _path_template = 'teams/{team_id}/datasets' - def __init__(self, - *args, - session: Session = None, - team_id: UUID = None, - project_id: Optional[UUID] = None): - # Handle positional arguments for backward compatibility - args = _pad_positional_args(args, 2) - self.project_id = project_id or args[0] - self.session = session or args[1] - if self.session is None: - raise TypeError("Missing one required argument: session.") - - self.team_id = _data_manager_deprecation_checks( - session=self.session, - project_id=self.project_id, - team_id=team_id, - obj_type="Datasets") - - # After the Data Manager deprecation - # this can be a Class Variable using the `teams/...` endpoint - @property - def _path_template(self): - if self.project_id is None: - return f'teams/{self.team_id}/datasets' - else: - return f'projects/{self.project_id}/datasets' + def __init__(self, *, session: Session, team_id: UUID): + self.session = session + self.team_id = team_id def build(self, data: dict) -> Dataset: """ @@ -468,7 +439,6 @@ def build(self, data: dict) -> Dataset: dataset = Dataset.build(data) dataset.team_id = self.team_id dataset.session = self.session - dataset.project_id = self.project_id return dataset def register(self, model: Dataset) -> Dataset: diff --git a/src/citrine/resources/file_link.py b/src/citrine/resources/file_link.py index e4e558d99..dd8824c17 100644 --- a/src/citrine/resources/file_link.py +++ b/src/citrine/resources/file_link.py @@ -7,15 +7,13 @@ from urllib.parse import urlparse from urllib.request import url2pathname from uuid import UUID -from warnings import warn from citrine._rest.collection import Collection from citrine._rest.resource import GEMDResource from citrine._serialization import properties from citrine._serialization.serializable import Serializable from citrine._session import Session -from citrine._utils.functions import _data_manager_deprecation_checks, _pad_positional_args, \ - rewrite_s3_links_locally, write_file_locally +from citrine._utils.functions import rewrite_s3_links_locally, write_file_locally from citrine.resources.response import Response from gemd.entity.dict_serializable import DictSerializableMeta from gemd.entity.bounds.base_bounds import BaseBounds @@ -198,28 +196,10 @@ class FileCollection(Collection[FileLink]): _collection_key = 'files' _resource = FileLink - def __init__( - self, - *args, - session: Session = None, - dataset_id: UUID = None, - team_id: UUID = None, - project_id: Optional[UUID] = None - ): - args = _pad_positional_args(args, 3) - self.project_id = project_id or args[0] - self.dataset_id = dataset_id or args[1] - self.session = session or args[2] - if self.session is None: - raise TypeError("Missing one required argument: session.") - if self.dataset_id is None: - raise TypeError("Missing one required argument: dataset_id.") - - self.team_id = _data_manager_deprecation_checks( - session=self.session, - project_id=self.project_id, - team_id=team_id, - obj_type="File Links") + def __init__(self, *, session: Session, dataset_id: UUID, team_id: UUID): + self.dataset_id = dataset_id + self.session = session + self.team_id = team_id def _get_path(self, uid: Optional[Union[UUID, str]] = None, @@ -727,15 +707,7 @@ def ingest(self, from citrine.resources.project import Project # noqa: F401 if build_table and project is None: - if self.project_id is None: - raise ValueError("Building a table requires a target project.") - else: - warn( - "Building a table with an implicit project is deprecated " - "and will be removed in v4. Please pass a project explicitly.", - DeprecationWarning - ) - project = self.project_id + raise ValueError("Building a table requires a target project.") def resolve_with_local(candidate: Union[FileLink, Path, str]) -> FileLink: """Resolve Path, str or FileLink to an absolute reference.""" diff --git a/src/citrine/resources/gemd_resource.py b/src/citrine/resources/gemd_resource.py index e72b89650..8ea8c7fc7 100644 --- a/src/citrine/resources/gemd_resource.py +++ b/src/citrine/resources/gemd_resource.py @@ -1,6 +1,6 @@ """Collection class for generic GEMD objects and templates.""" import re -from typing import Type, Union, List, Tuple, Iterable, Optional +from typing import Type, Union, List, Tuple, Iterable from uuid import UUID, uuid4 from gemd.entity.base_entity import BaseEntity @@ -15,7 +15,7 @@ from citrine.resources.delete import _async_gemd_batch_delete from citrine._session import Session from citrine._utils.batcher import Batcher -from citrine._utils.functions import _pad_positional_args, replace_objects_with_links, scrub_none +from citrine._utils.functions import replace_objects_with_links, scrub_none BATCH_SIZE = 50 @@ -26,23 +26,10 @@ class GEMDResourceCollection(DataConceptsCollection[DataConcepts]): _collection_key = 'storables' - def __init__( - self, - *args, - dataset_id: UUID = None, - session: Session = None, - team_id: UUID = None, - project_id: Optional[UUID] = None - ): - super().__init__(*args, - team_id=team_id, - dataset_id=dataset_id, - session=session, - project_id=project_id) - args = _pad_positional_args(args, 3) - self.project_id = project_id or args[0] - self.dataset_id = dataset_id or args[1] - self.session = session or args[2] + def __init__(self, *, dataset_id: UUID, session: Session, team_id: UUID): + super().__init__(team_id=team_id, dataset_id=dataset_id, session=session) + self.dataset_id = dataset_id + self.session = session self.team_id = team_id @classmethod diff --git a/src/citrine/resources/gemtables.py b/src/citrine/resources/gemtables.py index 71fb0def5..6252a301c 100644 --- a/src/citrine/resources/gemtables.py +++ b/src/citrine/resources/gemtables.py @@ -10,8 +10,8 @@ from citrine._serialization import properties from citrine._serialization.properties import UUID from citrine._session import Session -from citrine._utils.functions import format_escaped_url, _pad_positional_args, \ - rewrite_s3_links_locally, write_file_locally +from citrine._utils.functions import format_escaped_url, rewrite_s3_links_locally, \ + write_file_locally from citrine.jobs.job import JobSubmissionResponse, _poll_for_job_completion from citrine.resources.table_config import TableConfig, TableConfigCollection @@ -96,21 +96,10 @@ class GemTableCollection(Collection[GemTable]): _paginator: Paginator = GemTableVersionPaginator() _resource = GemTable - def __init__(self, - *args, - team_id: UUID = None, - project_id: UUID = None, - session: Session = None): - args = _pad_positional_args(args, 2) - self.project_id = project_id or args[0] - self.session: Session = session or args[1] + def __init__(self, *, team_id: UUID, project_id: UUID, session: Session): + self.project_id = project_id + self.session: Session = session self.team_id = team_id - if self.project_id is None: - raise TypeError("Missing one required argument: project_id.") - if self.team_id is None: - raise TypeError("Missing one required argument: team_id.") - if self.session is None: - raise TypeError("Missing one required argument: session.") def get(self, uid: Union[UUID, str], *, version: Optional[int] = None) -> GemTable: """Get a Table's metadata. If no version is specified, get the most recent version.""" diff --git a/src/citrine/resources/ingestion.py b/src/citrine/resources/ingestion.py index 916426db1..8b8807af8 100644 --- a/src/citrine/resources/ingestion.py +++ b/src/citrine/resources/ingestion.py @@ -1,7 +1,5 @@ -from deprecation import deprecated from typing import Optional, Union, Iterator, Iterable, Collection as TypingCollection from uuid import UUID -from warnings import warn from gemd.enumeration.base_enumeration import BaseEnumeration @@ -9,7 +7,6 @@ from citrine._rest.resource import Resource from citrine._serialization import properties from citrine._session import Session -from citrine._utils.functions import _data_manager_deprecation_checks, _pad_positional_args from citrine.exceptions import CitrineException, BadRequest from citrine.jobs.job import JobSubmissionResponse, JobFailureError, _poll_for_job_completion from citrine.resources.api_error import ApiError, ValidationError @@ -190,25 +187,10 @@ class Ingestion(Resource['Ingestion']): uid = properties.UUID('ingestion_id') """UUID: Unique uuid4 identifier of this ingestion.""" team_id = properties.Optional(properties.UUID, 'team_id', default=None) - _project_id = properties.Optional(properties.UUID, 'project_id', default=None) dataset_id = properties.UUID('dataset_id') session = properties.Object(Session, 'session', serializable=False) raise_errors = properties.Optional(properties.Boolean(), 'raise_errors', default=True) - @property - @deprecated(deprecated_in='3.11.0', removed_in='4.0.0', - details="The project_id attribute is deprecated since " - "dataset access is now controlled through teams.") - def project_id(self) -> Optional[UUID]: - """[DEPRECATED] The project ID associated with this ingest.""" - return self._project_id - - @project_id.setter - @deprecated(deprecated_in='3.9.0', removed_in='4.0.0', - details="Use the project argument instead of setting the project_id attribute.") - def project_id(self, value: Optional[UUID]): - self._project_id = value - def build_objects(self, *, build_table: bool = False, @@ -303,15 +285,7 @@ def build_objects_async(self, if not build_table: project_id = None elif project is None: - if self._project_id is None: - raise ValueError("Building a table requires a target project.") - else: - warn( - "Building a table with an implicit project is deprecated " - "and will be removed in v4. Please pass a project explicitly.", - DeprecationWarning - ) - project_id = self._project_id + raise ValueError("Building a table requires a target project.") elif isinstance(project, Project): project_id = project.uid elif isinstance(project, UUID): @@ -486,38 +460,12 @@ class IngestionCollection(Collection[Ingestion]): _individual_key = None _collection_key = None _resource = Ingestion + _path_template = 'teams/{team_id}/ingestions' - def __init__( - self, - *args, - session: Session = None, - team_id: UUID = None, - dataset_id: UUID = None, - project_id: Optional[UUID] = None - ): - args = _pad_positional_args(args, 3) - self.project_id = project_id or args[0] - self.dataset_id = dataset_id or args[1] - self.session = session or args[2] - if self.session is None: - raise TypeError("Missing one required argument: session.") - if self.dataset_id is None: - raise TypeError("Missing one required argument: dataset_id.") - - self.team_id = _data_manager_deprecation_checks( - session=self.session, - project_id=self.project_id, - team_id=team_id, - obj_type="Ingestions") - - # After the Data Manager deprecation, - # this can be a Class Variable using the `teams/...` endpoint - @property - def _path_template(self): - if self.project_id is None: - return f'teams/{self.team_id}/ingestions' - else: - return f'projects/{self.project_id}/ingestions' + def __init__(self, *, session: Session, team_id: UUID, dataset_id: UUID): + self.dataset_id = dataset_id + self.session = session + self.team_id = team_id def build_from_file_links(self, file_links: TypingCollection[FileLink], diff --git a/src/citrine/resources/predictor_evaluation_execution.py b/src/citrine/resources/predictor_evaluation_execution.py deleted file mode 100644 index 50b392708..000000000 --- a/src/citrine/resources/predictor_evaluation_execution.py +++ /dev/null @@ -1,172 +0,0 @@ -"""Resources that represent both individual and collections of predictor evaluation executions.""" -from deprecation import deprecated -from functools import partial -from typing import Optional, Union, Iterator -from uuid import UUID - -from citrine._rest.collection import Collection -from citrine._rest.resource import PredictorRef -from citrine._session import Session -from citrine._utils.functions import format_escaped_url -from citrine.informatics.executions import predictor_evaluation_execution -from citrine.resources.response import Response - - -class PredictorEvaluationExecutionCollection(Collection["PredictorEvaluationExecution"]): - """A collection of PredictorEvaluationExecutions.""" - - _path_template = '/projects/{project_id}/predictor-evaluation-executions' # noqa - _individual_key = None - _collection_key = 'response' - _resource = predictor_evaluation_execution.PredictorEvaluationExecution - - @deprecated(deprecated_in="3.23.0", removed_in="4.0.0", - details="Predictor evaluation workflows are being eliminated in favor of directly" - "evaluating predictors. Please use Project.predictor_evaluations instead.") - def __init__(self, - project_id: UUID, - session: Session, - workflow_id: Optional[UUID] = None): - self.project_id: UUID = project_id - self.session: Session = session - self.workflow_id: Optional[UUID] = workflow_id - - def build(self, data: dict) -> predictor_evaluation_execution.PredictorEvaluationExecution: - """Build an individual PredictorEvaluationExecution.""" - execution = predictor_evaluation_execution.PredictorEvaluationExecution.build(data) - execution._session = self.session - execution.project_id = self.project_id - return execution - - @deprecated(deprecated_in="3.23.0", removed_in="4.0.0", - details="Please use PredictorEvaluationCollection.trigger instead.") - def trigger(self, - predictor_id: UUID, - *, - predictor_version: Optional[Union[int, str]] = None, - random_state: Optional[int] = None): - """Trigger a predictor evaluation execution against a predictor. - - Parameters - ----------- - predictor_id: UUID - ID of the predictor to evaluate. - predictor_version: Union[int, str], optional - The version of the predictor to evaluate. - random_state: int, optional - Seeds the evaluators' random number generator so that the results are repeatable. - - """ - if self.workflow_id is None: - msg = "Cannot trigger a predictor evaluation execution without knowing the " \ - "predictor evaluation workflow. Use workflow.executions.trigger instead of " \ - "project.predictor_evaluation_executions.trigger" - raise RuntimeError(msg) - path = format_escaped_url( - '/projects/{project_id}/predictor-evaluation-workflows/{workflow_id}/executions', - project_id=self.project_id, - workflow_id=self.workflow_id - ) - - params = dict() - if random_state is not None: - params["random_state"] = random_state - - payload = PredictorRef(predictor_id, predictor_version).dump() - data = self.session.post_resource(path, payload, params=params, version='v2') - - return self.build(data) - - @deprecated(deprecated_in="3.23.0", removed_in="4.0.0") - def register(self, - model: predictor_evaluation_execution.PredictorEvaluationExecution - ) -> predictor_evaluation_execution.PredictorEvaluationExecution: - """Cannot register an execution.""" - raise NotImplementedError("Cannot register a PredictorEvaluationExecution.") - - @deprecated(deprecated_in="3.23.0", removed_in="4.0.0") - def update(self, - model: predictor_evaluation_execution.PredictorEvaluationExecution - ) -> predictor_evaluation_execution.PredictorEvaluationExecution: - """Cannot update an execution.""" - raise NotImplementedError("Cannot update a PredictorEvaluationExecution.") - - @deprecated(deprecated_in="3.23.0", removed_in="4.0.0", - details="Please use PredictorEvaluation.archive") - def archive(self, uid: Union[UUID, str]): - """Archive a predictor evaluation execution. - - Parameters - ---------- - uid: Union[UUID, str] - Unique identifier of the execution to archive - - """ - self._put_resource_ref('archive', uid) - - @deprecated(deprecated_in="3.23.0", removed_in="4.0.0", - details="Please use PredictorEvaluation.restore") - def restore(self, uid: Union[UUID, str]): - """Restore an archived predictor evaluation execution. - - Parameters - ---------- - uid: Union[UUID, str] - Unique identifier of the execution to restore - - """ - self._put_resource_ref('restore', uid) - - @deprecated(deprecated_in="3.23.0", removed_in="4.0.0", - details="Please use PredictorEvaluation.list") - def list(self, - *, - per_page: int = 100, - predictor_id: Optional[UUID] = None, - predictor_version: Optional[Union[int, str]] = None - ) -> Iterator[predictor_evaluation_execution.PredictorEvaluationExecution]: - """ - Paginate over the elements of the collection. - - Parameters - --------- - per_page: int, optional - Max number of results to return per page. Default is 100. This parameter - is used when making requests to the backend service. If the page parameter - is specified it limits the maximum number of elements in the response. - predictor_id: uuid, optional - list executions that targeted the predictor with this id - predictor_version: Union[int, str], optional - list executions that targeted the predictor with this version - - Returns - ------- - Iterator[PredictorEvaluationExecution] - The matching predictor evaluation executions. - - """ - params = {} - if predictor_id is not None: - params["predictor_id"] = str(predictor_id) - if predictor_version is not None: - params["predictor_version"] = predictor_version - if self.workflow_id is not None: - params["workflow_id"] = str(self.workflow_id) - - fetcher = partial(self._fetch_page, additional_params=params) - return self._paginator.paginate(page_fetcher=fetcher, - collection_builder=self._build_collection_elements, - per_page=per_page) - - @deprecated(deprecated_in="3.23.0", removed_in="4.0.0") - def delete(self, uid: Union[UUID, str]) -> Response: - """Predictor Evaluation Executions cannot be deleted; they can be archived instead.""" - raise NotImplementedError( - "Predictor Evaluation Executions cannot be deleted; they can be archived instead.") - - @deprecated(deprecated_in="3.23.0", removed_in="4.0.0", - details="Please use PredictorEvaluation.get") - def get(self, - uid: Union[UUID, str]) -> predictor_evaluation_execution.PredictorEvaluationExecution: - """Get a particular element of the collection.""" - return super().get(uid) diff --git a/src/citrine/resources/predictor_evaluation_workflow.py b/src/citrine/resources/predictor_evaluation_workflow.py deleted file mode 100644 index e41e20ebc..000000000 --- a/src/citrine/resources/predictor_evaluation_workflow.py +++ /dev/null @@ -1,133 +0,0 @@ -"""Resources that represent both individual and collections of workflow executions.""" -from deprecation import deprecated -from typing import Iterator, Optional, Union -from uuid import UUID - -from citrine._rest.collection import Collection -from citrine._session import Session -from citrine.informatics.workflows import PredictorEvaluationWorkflow -from citrine.resources.response import Response - - -class PredictorEvaluationWorkflowCollection(Collection[PredictorEvaluationWorkflow]): - """A collection of PredictorEvaluationWorkflows.""" - - _path_template = '/projects/{project_id}/predictor-evaluation-workflows' - _individual_key = None - _collection_key = 'response' - _resource = PredictorEvaluationWorkflow - - @deprecated(deprecated_in="3.23.0", removed_in="4.0.0", - details="Predictor evaluation workflows are being eliminated in favor of directly" - "evaluating predictors. Please use Project.predictor_evaluations instead.") - def __init__(self, project_id: UUID, session: Session): - self.project_id: UUID = project_id - self.session: Session = session - - def build(self, data: dict) -> PredictorEvaluationWorkflow: - """Build an individual PredictorEvaluationExecution.""" - workflow = PredictorEvaluationWorkflow.build(data) - workflow._session = self.session - workflow.project_id = self.project_id - return workflow - - @deprecated(deprecated_in="3.23.0", removed_in="4.0.0", - details="Please use PredictorEvaluations instead, which doesn't store workflows.") - def archive(self, uid: Union[UUID, str]): - """Archive a predictor evaluation workflow. - - Parameters - ---------- - uid: Union[UUID, str] - Unique identifier of the workflow to archive - - """ - return self._put_resource_ref('archive', uid) - - @deprecated(deprecated_in="3.23.0", removed_in="4.0.0", - details="Please use PredictorEvaluations instead, which doesn't store workflows.") - def restore(self, uid: Union[UUID, str] = None): - """Restore an archived predictor evaluation workflow. - - Parameters - ---------- - uid: Union[UUID, str] - Unique identifier of the workflow to restore - - """ - return self._put_resource_ref('restore', uid) - - @deprecated(deprecated_in="3.23.0", removed_in="4.0.0") - def delete(self, uid: Union[UUID, str]) -> Response: - """Predictor Evaluation Workflows cannot be deleted; they can be archived instead.""" - raise NotImplementedError( - "Predictor Evaluation Workflows cannot be deleted; they can be archived instead.") - - @deprecated(deprecated_in="3.23.0", removed_in="4.0.0", - details="Please use PredictorEvaluations.trigger_default instead. It doesn't store" - " a workflow, but it triggers an evaluation with the default evaluators.") - def create_default(self, - *, - predictor_id: UUID, - predictor_version: Optional[Union[int, str]] = None) \ - -> PredictorEvaluationWorkflow: - """Create a default predictor evaluation workflow for a predictor and execute it. - - The current default predictor evaluation workflow performs 5-fold, 1-trial cross-validation - on all valid predictor responses. Valid responses are those that are **not** produced by the - following predictors: - - * :class:`~citrine.informatics.predictors.generalized_mean_property_predictor.GeneralizedMeanPropertyPredictor` - * :class:`~citrine.informatics.predictors.mean_property_predictor.MeanPropertyPredictor` - * :class:`~citrine.informatics.predictors.ingredient_fractions_predictor.IngredientFractionsPredictor` - * :class:`~citrine.informatics.predictors.ingredients_to_simple_mixture_predictor.IngredientsToSimpleMixturePredictor` - * :class:`~citrine.informatics.predictors.ingredients_to_formulation_predictor.IngredientsToFormulationPredictor` - * :class:`~citrine.informatics.predictors.label_fractions_predictor.LabelFractionsPredictor` - * :class:`~citrine.informatics.predictors.molecular_structure_featurizer.MolecularStructureFeaturizer` - * :class:`~citrine.informatics.predictors.simple_mixture_predictor.SimpleMixturePredictor` - - If there are no valid responses, a default workflow is not created. - - Parameters - ---------- - predictor_id: UUID - Unique identifier of the predictor used to create a default workflow - predictor_version: Option[Union[int, str]] - The version of the predictor used to create a default workflow - - Returns - ------- - PredictorEvaluationWorkflow - Default workflow - - """ # noqa: E501,W505 - url = self._get_path('default') - payload = {'predictor_id': str(predictor_id)} - if predictor_version: - payload['predictor_version'] = predictor_version - data = self.session.post_resource(url, payload) - return self.build(data) - - @deprecated(deprecated_in="3.23.0", removed_in="4.0.0", - details="Please use PredictorEvaluations instead, which doesn't store workflows.") - def register(self, model: PredictorEvaluationWorkflow) -> PredictorEvaluationWorkflow: - """Create a new element of the collection by registering an existing resource.""" - return super().register(model) - - @deprecated(deprecated_in="3.23.0", removed_in="4.0.0", - details="Please use PredictorEvaluations instead, which doesn't store workflows.") - def list(self, *, per_page: int = 100) -> Iterator[PredictorEvaluationWorkflow]: - """Paginate over the elements of the collection.""" - return super().list(per_page=per_page) - - @deprecated(deprecated_in="3.23.0", removed_in="4.0.0", - details="Please use PredictorEvaluations instead, which doesn't store workflows.") - def update(self, model: PredictorEvaluationWorkflow) -> PredictorEvaluationWorkflow: - """Update a particular element of the collection.""" - return super().update(model) - - @deprecated(deprecated_in="3.23.0", removed_in="4.0.0", - details="Please use PredictorEvaluations instead, which doesn't store workflows.") - def get(self, uid: Union[UUID, str]) -> PredictorEvaluationWorkflow: - """Get a particular element of the collection.""" - return super().get(uid) diff --git a/src/citrine/resources/project.py b/src/citrine/resources/project.py index 4e9777f1f..ee3a7388b 100644 --- a/src/citrine/resources/project.py +++ b/src/citrine/resources/project.py @@ -1,46 +1,19 @@ """Resources that represent both individual and collections of projects.""" -from deprecation import deprecated from functools import partial -from typing import Optional, Dict, List, Union, Iterable, Tuple, Iterator +from typing import Optional, Dict, List, Union, Iterable, Iterator from uuid import UUID -from warnings import warn - -from gemd.entity.base_entity import BaseEntity -from gemd.entity.link_by_uid import LinkByUID from citrine._rest.collection import Collection from citrine._rest.resource import Resource, ResourceTypeEnum from citrine._serialization import properties from citrine._session import Session from citrine._utils.functions import format_escaped_url -from citrine.resources.api_error import ApiError from citrine.resources.branch import BranchCollection -from citrine.resources.dataset import DatasetCollection -from citrine.resources.delete import _async_gemd_batch_delete from citrine.resources.descriptors import DescriptorMethods from citrine.resources.design_space import DesignSpaceCollection from citrine.resources.design_workflow import DesignWorkflowCollection -from citrine.resources.gemd_resource import GEMDResourceCollection from citrine.resources.gemtables import GemTableCollection -from citrine.resources.ingredient_run import IngredientRunCollection -from citrine.resources.ingredient_spec import IngredientSpecCollection -from citrine.resources.material_run import MaterialRunCollection -from citrine.resources.material_spec import MaterialSpecCollection -from citrine.resources.material_template import MaterialTemplateCollection -from citrine.resources.measurement_run import MeasurementRunCollection -from citrine.resources.measurement_spec import MeasurementSpecCollection -from citrine.resources.measurement_template import MeasurementTemplateCollection -from citrine.resources.parameter_template import ParameterTemplateCollection -from citrine.resources.property_template import PropertyTemplateCollection -from citrine.resources.condition_template import ConditionTemplateCollection -from citrine.resources.process_run import ProcessRunCollection -from citrine.resources.process_spec import ProcessSpecCollection -from citrine.resources.process_template import ProcessTemplateCollection from citrine.resources.predictor import PredictorCollection -from citrine.resources.predictor_evaluation_execution import \ - PredictorEvaluationExecutionCollection -from citrine.resources.predictor_evaluation_workflow import \ - PredictorEvaluationWorkflowCollection from citrine.resources.predictor_evaluation import PredictorEvaluationCollection from citrine.resources.generative_design_execution import \ GenerativeDesignExecutionCollection @@ -142,16 +115,6 @@ def descriptors(self) -> DescriptorMethods: """Return a resource containing a set of methods returning descriptors.""" return DescriptorMethods(project_id=self.uid, session=self.session) - @property - def predictor_evaluation_workflows(self) -> PredictorEvaluationWorkflowCollection: - """Return a collection representing all visible predictor evaluation workflows.""" - return PredictorEvaluationWorkflowCollection(project_id=self.uid, session=self.session) - - @property - def predictor_evaluation_executions(self) -> PredictorEvaluationExecutionCollection: - """Return a collection representing all visible predictor evaluation executions.""" - return PredictorEvaluationExecutionCollection(project_id=self.uid, session=self.session) - @property def predictor_evaluations(self) -> PredictorEvaluationCollection: """Return a collection representing all visible predictor evaluations.""" @@ -167,168 +130,11 @@ def generative_design_executions(self) -> GenerativeDesignExecutionCollection: """Return a collection representing all visible generative design executions.""" return GenerativeDesignExecutionCollection(project_id=self.uid, session=self.session) - @property - @deprecated(deprecated_in="3.4.0", removed_in="4.0.0", - details="Please use 'Team.datasets' instead.'") - def datasets(self) -> DatasetCollection: - """Return a resource representing all visible datasets.""" - return DatasetCollection(team_id=self.team_id, project_id=self.uid, session=self.session) - @property def tables(self) -> GemTableCollection: """Return a resource representing all visible Tables.""" return GemTableCollection(team_id=self.team_id, project_id=self.uid, session=self.session) - @property - @deprecated(deprecated_in="3.4.0", removed_in="4.0.0", - details="Please use 'Team.property_templates' instead.'") - def property_templates(self) -> PropertyTemplateCollection: - """Return a resource representing all property templates in this dataset.""" - return PropertyTemplateCollection(project_id=self.uid, - dataset_id=None, - session=self.session, - team_id=self.team_id) - - @property - @deprecated(deprecated_in="3.4.0", removed_in="4.0.0", - details="Please use 'Team.condition_templates' instead.'") - def condition_templates(self) -> ConditionTemplateCollection: - """Return a resource representing all condition templates in this dataset.""" - return ConditionTemplateCollection(project_id=self.uid, - dataset_id=None, - session=self.session, - team_id=self.team_id) - - @property - @deprecated(deprecated_in="3.4.0", removed_in="4.0.0", - details="Please use 'Team.parameter_templates' instead.'") - def parameter_templates(self) -> ParameterTemplateCollection: - """Return a resource representing all parameter templates in this dataset.""" - return ParameterTemplateCollection(project_id=self.uid, - dataset_id=None, - session=self.session, - team_id=self.team_id) - - @property - @deprecated(deprecated_in="3.4.0", removed_in="4.0.0", - details="Please use 'Team.material_templates' instead.'") - def material_templates(self) -> MaterialTemplateCollection: - """Return a resource representing all material templates in this dataset.""" - return MaterialTemplateCollection(project_id=self.uid, - dataset_id=None, - session=self.session, - team_id=self.team_id) - - @property - @deprecated(deprecated_in="3.4.0", removed_in="4.0.0", - details="Please use 'Team.measurement_templates' instead.'") - def measurement_templates(self) -> MeasurementTemplateCollection: - """Return a resource representing all measurement templates in this dataset.""" - return MeasurementTemplateCollection(project_id=self.uid, - dataset_id=None, - session=self.session, - team_id=self.team_id) - - @property - @deprecated(deprecated_in="3.4.0", removed_in="4.0.0", - details="Please use 'Team.process_templates' instead.'") - def process_templates(self) -> ProcessTemplateCollection: - """Return a resource representing all process templates in this dataset.""" - return ProcessTemplateCollection(project_id=self.uid, - dataset_id=None, - session=self.session, - team_id=self.team_id) - - @property - @deprecated(deprecated_in="3.4.0", removed_in="4.0.0", - details="Please use 'Team.process_runs' instead.'") - def process_runs(self) -> ProcessRunCollection: - """Return a resource representing all process runs in this dataset.""" - return ProcessRunCollection(project_id=self.uid, - dataset_id=None, - session=self.session, - team_id=self.team_id) - - @property - @deprecated(deprecated_in="3.4.0", removed_in="4.0.0", - details="Please use 'Team.measurement_runs' instead.'") - def measurement_runs(self) -> MeasurementRunCollection: - """Return a resource representing all measurement runs in this dataset.""" - return MeasurementRunCollection(project_id=self.uid, - dataset_id=None, - session=self.session, - team_id=self.team_id) - - @property - @deprecated(deprecated_in="3.4.0", removed_in="4.0.0", - details="Please use 'Team.material_runs' instead.'") - def material_runs(self) -> MaterialRunCollection: - """Return a resource representing all material runs in this dataset.""" - return MaterialRunCollection(project_id=self.uid, - dataset_id=None, - session=self.session, - team_id=self.team_id) - - @property - @deprecated(deprecated_in="3.4.0", removed_in="4.0.0", - details="Please use 'Team.ingredient_runs' instead.'") - def ingredient_runs(self) -> IngredientRunCollection: - """Return a resource representing all ingredient runs in this dataset.""" - return IngredientRunCollection(project_id=self.uid, - dataset_id=None, - session=self.session, - team_id=self.team_id) - - @property - @deprecated(deprecated_in="3.4.0", removed_in="4.0.0", - details="Please use 'Team.process_specs' instead.'") - def process_specs(self) -> ProcessSpecCollection: - """Return a resource representing all process specs in this dataset.""" - return ProcessSpecCollection(project_id=self.uid, - dataset_id=None, - session=self.session, - team_id=self.team_id) - - @property - @deprecated(deprecated_in="3.4.0", removed_in="4.0.0", - details="Please use 'Team.measurement_specs' instead.'") - def measurement_specs(self) -> MeasurementSpecCollection: - """Return a resource representing all measurement specs in this dataset.""" - return MeasurementSpecCollection(project_id=self.uid, - dataset_id=None, - session=self.session, - team_id=self.team_id) - - @property - @deprecated(deprecated_in="3.4.0", removed_in="4.0.0", - details="Please use 'Team.material_specs' instead.'") - def material_specs(self) -> MaterialSpecCollection: - """Return a resource representing all material specs in this dataset.""" - return MaterialSpecCollection(project_id=self.uid, - dataset_id=None, - session=self.session, - team_id=self.team_id) - - @property - @deprecated(deprecated_in="3.4.0", removed_in="4.0.0", - details="Please use 'Team.ingredient_specs' instead.'") - def ingredient_specs(self) -> IngredientSpecCollection: - """Return a resource representing all ingredient specs in this dataset.""" - return IngredientSpecCollection(project_id=self.uid, - dataset_id=None, - session=self.session, - team_id=self.team_id) - - @property - @deprecated(deprecated_in="3.4.0", removed_in="4.0.0", - details="Please use 'Team.gemd' instead.'") - def gemd(self) -> GEMDResourceCollection: - """Return a resource representing all GEMD objects/templates in this dataset.""" - return GEMDResourceCollection(project_id=self.uid, - dataset_id=None, - session=self.session, - team_id=self.team_id) - @property def table_configs(self) -> TableConfigCollection: """Return a resource representing all Table Configs in the project.""" @@ -358,11 +164,8 @@ def publish(self, *, resource: Resource): resource_access = resource.access_control_dict() resource_type = resource_access["type"] if resource_type == ResourceTypeEnum.DATASET: - warn("Newly created datasets belong to a team, making this is unncessary. If it was " - "created before 3.4.0, publish will work as before. Calling publish on datasets " - "will be disabled in 4.0.0, at which time all datasets will be automatically " - "published.", - DeprecationWarning) + raise ValueError("Datasets already belong to a team, so publishing is unncessary.") + self.session.checked_post( f"{self._path()}/published-resources/{resource_type}/batch-publish", version='v3', @@ -387,11 +190,8 @@ def un_publish(self, *, resource: Resource): resource_access = resource.access_control_dict() resource_type = resource_access["type"] if resource_type == ResourceTypeEnum.DATASET: - warn("Newly created datasets belong to a team, making un_publish a no-op. If it was " - "created before 3.4.0, un_publish will work as before. Calling un_publish on " - "datasets will be disabled in 4.0.0, at which time all datasets will be " - "automatically published.", - DeprecationWarning) + raise ValueError("Datasets belong to a team, so unpublishing is meaningless.") + self.session.checked_post( f"{self._path()}/published-resources/{resource_type}/batch-un-publish", version='v3', @@ -416,11 +216,8 @@ def pull_in_resource(self, *, resource: Resource): resource_access = resource.access_control_dict() resource_type = resource_access["type"] if resource_type == ResourceTypeEnum.DATASET: - warn("Newly created datasets belong to a team, making pull_in_resource a no-op. If it " - "was created before 3.4.0, pull_in_resource will work as before. Calling " - "pull_in_resource on datasets will be disabled in 4.0.0, at which time all " - "datasets will be automatically published.", - DeprecationWarning) + raise ValueError("Pulling a dataset into a project is unnecessary.") + base_url = f'/teams/{self.team_id}{self._path()}' self.session.checked_post( f'{base_url}/outside-resources/{resource_type}/batch-pull-in', @@ -428,27 +225,6 @@ def pull_in_resource(self, *, resource: Resource): json={'ids': [resource_access["id"]]}) return True - def owned_dataset_ids(self) -> List[str]: - """ - List all the ids of the datasets owned by the current project. - - Returns - ------- - List[str] - The ids of the modules owned by current project - - """ - warn( - "Datasets are no be longer owned by Projects. To find the Datasets owned by your " - "Team, use Team.owned_dataset_ids().", - DeprecationWarning - ) - query_params = {"userId": "", "domain": self._path(), "action": "WRITE"} - response = self.session.get_resource("/DATASET/authorized-ids", - params=query_params, - version="v3") - return response['ids'] - def list_members(self) -> Union[List[ProjectMember], List["TeamMember"]]: # noqa: F821 """ List all of the members in the current project. @@ -467,53 +243,6 @@ def list_members(self) -> Union[List[ProjectMember], List["TeamMember"]]: # noq parent_team = team_collection.get(self.team_id) return parent_team.list_members() - @deprecated(deprecated_in="3.4.0", removed_in="4.0.0", - details="Please use 'Team.gemd_batch_delete' instead.'") - def gemd_batch_delete(self, - id_list: List[Union[LinkByUID, UUID, str, BaseEntity]], - *, - timeout: float = 2 * 60, - polling_delay: float = 1.0) -> List[Tuple[LinkByUID, ApiError]]: - """ - Remove a set of GEMD objects. - - You may provide GEMD objects that reference each other, and the objects - will be removed in the appropriate order. - - A failure will be returned if the object cannot be deleted due to an external - reference. - - You must have Write access on the associated datasets for each object. - - Parameters - ---------- - id_list: List[Union[LinkByUID, UUID, str, BaseEntity]] - A list of the IDs of data objects to be removed. They can be passed - as a LinkByUID tuple, a UUID, a string, or the object itself. A UUID - or string is assumed to be a Citrine ID, whereas a LinkByUID or - BaseEntity can also be used to provide an external ID. - timeout: float - Amount of time to wait on the job (in seconds) before giving up. Defaults - to 2 minutes. Note that this number has no effect on the underlying job - itself, which can also time out server-side. - polling_delay: float - How long to delay between each polling retry attempt (in seconds). - - Returns - ------- - List[Tuple[LinkByUID, ApiError]] - A list of (LinkByUID, api_error) for each failure to delete an object. - Note that this method doesn't raise an exception if an object fails to be - deleted. - - """ - return _async_gemd_batch_delete(id_list=id_list, - team_id=self.team_id, - session=self.session, - dataset_id=None, - timeout=timeout, - polling_delay=polling_delay) - class ProjectCollection(Collection[Project]): """ diff --git a/src/citrine/resources/table_config.py b/src/citrine/resources/table_config.py index 1421ef82e..ad03a4de5 100644 --- a/src/citrine/resources/table_config.py +++ b/src/citrine/resources/table_config.py @@ -1,7 +1,6 @@ from copy import copy from typing import List, Union, Optional, Tuple from uuid import UUID -from warnings import warn from gemd.entity.object import MaterialRun @@ -12,7 +11,7 @@ from citrine._rest.resource import Resource, ResourceTypeEnum from citrine._serialization import properties from citrine._session import Session -from citrine._utils.functions import format_escaped_url, _pad_positional_args +from citrine._utils.functions import format_escaped_url from citrine.resources.dataset import DatasetCollection from citrine.resources.data_concepts import CITRINE_SCOPE, _make_link_by_uid from citrine.resources.process_template import ProcessTemplate @@ -28,7 +27,6 @@ from typing import TYPE_CHECKING if TYPE_CHECKING: # pragma: no cover - from citrine.resources.project import Project from citrine.resources.team import Team @@ -213,8 +211,7 @@ def add_columns(self, *, def add_all_ingredients(self, *, process_template: Union[LinkByUID, ProcessTemplate, str, UUID], - project: 'Project' = None, - team: 'Team' = None, + team: 'Team', quantity_dimension: IngredientQuantityDimension, scope: str = CITRINE_SCOPE, unit: Optional[str] = None @@ -229,8 +226,8 @@ def add_all_ingredients(self, *, ------------ process_template: Union[LinkByUID, ProcessTemplate, str, UUID] representation of a registered process template - project: Project - a project that has access to the process template + team: Team + a team that has access to the process template quantity_dimension: IngredientQuantityDimension the dimension in which to report ingredient quantities scope: Optional[str] @@ -239,16 +236,6 @@ def add_all_ingredients(self, *, the units for the quantity, if selecting Absolute Quantity """ - if project is not None: - warn("Adding ingredients to a table config through a project is deprecated as of " - "3.4.0, and will be removed in 4.0.0. Please use a team instead.", - DeprecationWarning) - principal = project - elif team is not None: - principal = team - else: - raise TypeError("Missing 1 required argument: team") - dimension_display = { IngredientQuantityDimension.ABSOLUTE: "absolute quantity", IngredientQuantityDimension.MASS: "mass fraction", @@ -256,7 +243,7 @@ def add_all_ingredients(self, *, IngredientQuantityDimension.NUMBER: "number fraction" } link = _make_link_by_uid(process_template) - process: ProcessTemplate = principal.process_templates.get(uid=link) + process: ProcessTemplate = team.process_templates.get(uid=link) if not process.allowed_names: raise RuntimeError( "Cannot add ingredients for process template \'{}\' because it has no defined " @@ -320,8 +307,7 @@ def add_all_ingredients(self, *, def add_all_ingredients_in_output(self, *, process_templates: List[LinkByUID], - project: 'Project' = None, - team: 'Team' = None, + team: 'Team', quantity_dimension: IngredientQuantityDimension, scope: str = CITRINE_SCOPE, unit: Optional[str] = None @@ -339,8 +325,8 @@ def add_all_ingredients_in_output(self, *, process_templates: List[LinkByUID] registered process templates from which to pull allowed ingredients and at which to halt searching - project: Project - a project that has access to the process template + team: Team + a team that has access to the process template quantity_dimension: IngredientQuantityDimension the dimension in which to report ingredient quantities scope: Optional[str] @@ -349,16 +335,6 @@ def add_all_ingredients_in_output(self, *, the units for the quantity, if selecting Absolute Quantity """ - if project is not None: - warn("Adding ingredients to a table config through a project is deprecated as of " - "3.4.0, and will be removed in 4.0.0. Please use a team instead.", - DeprecationWarning) - principal = project - elif team is not None: - principal = team - else: - raise TypeError("Missing 1 required argument: team") - dimension_display = { IngredientQuantityDimension.ABSOLUTE: "absolute quantity", IngredientQuantityDimension.MASS: "mass fraction", @@ -367,7 +343,7 @@ def add_all_ingredients_in_output(self, *, } union_allowed_names = [] for process_template_link in process_templates: - process: ProcessTemplate = principal.process_templates.get(process_template_link) + process: ProcessTemplate = team.process_templates.get(process_template_link) if not process.allowed_names: raise RuntimeError( f"Cannot add ingredients for process template '{process.name}' " @@ -443,15 +419,10 @@ class TableConfigCollection(Collection[TableConfig]): # definition) are necessary _individual_key = None - def __init__(self, *args, team_id: UUID, project_id: UUID = None, session: Session = None): - args = _pad_positional_args(args, 2) - self.project_id = project_id or args[0] - self.session: Session = session or args[1] + def __init__(self, *, team_id: UUID, project_id: UUID, session: Session): + self.project_id = project_id + self.session: Session = session self.team_id = team_id - if self.project_id is None: - raise TypeError("Missing one required argument: project_id.") - if self.session is None: - raise TypeError("Missing one required argument: session.") def get(self, uid: Union[UUID, str], *, version: Optional[int] = None): """Get a table config. diff --git a/tests/_serialization/test_resource.py b/tests/_serialization/test_resource.py deleted file mode 100644 index 78bb4a1af..000000000 --- a/tests/_serialization/test_resource.py +++ /dev/null @@ -1,15 +0,0 @@ -from uuid import uuid4 - -from citrine._rest.resource import ResourceRef - - -def test_module_ref_serialization(): - # Given - m_uid = uuid4() - ref = ResourceRef(uid=m_uid) - - # When - ref_data = ref.dump() - - # Then - assert ref_data['module_uid'] == str(m_uid) diff --git a/tests/conftest.py b/tests/conftest.py index b841139bc..ea573c013 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -327,8 +327,7 @@ def valid_auto_ml_predictor_data(valid_gem_data_source_dict): description='Predicts z from input x', inputs=[x.dump()], outputs=[z.dump()], - estimators=[AutoMLEstimator.RANDOM_FOREST.value], - training_data=[] + estimators=[AutoMLEstimator.RANDOM_FOREST.value] ) @@ -550,8 +549,7 @@ def valid_mean_property_predictor_data(): p=2.0, impute_properties=True, default_properties={'density': 1.0}, - label='solvent', - training_data=[] + label='solvent' ) @@ -660,8 +658,7 @@ def valid_simple_mixture_predictor_data(): return dict( type='SimpleMixture', name='Simple mixture predictor', - description='simple mixture description', - training_data=[] + description='simple mixture description' ) diff --git a/tests/informatics/test_constraints.py b/tests/informatics/test_constraints.py index 78fb32f69..18d039e81 100644 --- a/tests/informatics/test_constraints.py +++ b/tests/informatics/test_constraints.py @@ -184,32 +184,14 @@ def test_ingredient_ratio_interaction(ingredient_ratio_constraint): newval_set = {"foobasis1"} ingredient_ratio_constraint.basis_ingredients = newval_set assert ingredient_ratio_constraint.basis_ingredients == newval_set - with pytest.deprecated_call(): - assert ingredient_ratio_constraint.basis_ingredient_names == newval_set - - newval_set = {"foobasis2"} - with pytest.deprecated_call(): - ingredient_ratio_constraint.basis_ingredient_names = newval_set - assert ingredient_ratio_constraint.basis_ingredients == newval_set - with pytest.deprecated_call(): - assert ingredient_ratio_constraint.basis_ingredient_names == newval_set newval_set = {"foolabelbasis1"} ingredient_ratio_constraint.basis_labels = newval_set assert ingredient_ratio_constraint.basis_labels == newval_set - with pytest.deprecated_call(): - assert ingredient_ratio_constraint.basis_label_names == newval_set - - newval_set = {"foolabelbasis1"} - with pytest.deprecated_call(): - ingredient_ratio_constraint.basis_label_names = newval_set - assert ingredient_ratio_constraint.basis_labels == newval_set - with pytest.deprecated_call(): - assert ingredient_ratio_constraint.basis_label_names == newval_set def test_range_defaults(): - """Check that deprecated and default values work as expected.""" + """Check that default values work as expected.""" assert ScalarRangeConstraint(descriptor_key="x").lower_bound is None assert ScalarRangeConstraint(descriptor_key="x").upper_bound is None assert ScalarRangeConstraint(descriptor_key="x").lower_inclusive is True diff --git a/tests/informatics/test_predictors.py b/tests/informatics/test_predictors.py index 6eff41b5f..e1f7c1c57 100644 --- a/tests/informatics/test_predictors.py +++ b/tests/informatics/test_predictors.py @@ -83,7 +83,7 @@ def chemical_featurizer() -> ChemicalFormulaFeaturizer: input_descriptor=ChemicalFormulaDescriptor("formula"), features=["standard"], excludes=None, - powers=[1, 2] + powers=[1.0, 2.0] ) @@ -274,9 +274,8 @@ def test_chemical_featurizer(chemical_featurizer): assert chemical_featurizer.input_descriptor == ChemicalFormulaDescriptor("formula") assert chemical_featurizer.features == ["standard"] assert chemical_featurizer.excludes == [] - with pytest.warns(UserWarning): - assert chemical_featurizer.powers == [1, 2] - with pytest.warns(PendingDeprecationWarning): + assert chemical_featurizer.powers == [1.0, 2.0] + with pytest.warns(DeprecationWarning): assert chemical_featurizer.powers_as_float == [1.0, 2.0] assert str(chemical_featurizer) == "" @@ -287,15 +286,14 @@ def test_chemical_featurizer(chemical_featurizer): 'input': ChemicalFormulaDescriptor("formula").dump(), 'features': ['standard'], 'excludes': [], - 'powers': [1, 2], + 'powers': [1.0, 2.0], 'type': 'ChemicalFormulaFeaturizer' } - chemical_featurizer.powers = [0.5, -1] - with pytest.warns(PendingDeprecationWarning): + chemical_featurizer.powers = [0.5, -1.0] + with pytest.warns(DeprecationWarning): assert chemical_featurizer.powers_as_float == [0.5, -1.0] - with pytest.warns(UserWarning): - assert chemical_featurizer.powers == [0, -1] + assert chemical_featurizer.powers == [0.5, -1.0] def test_auto_ml(auto_ml): @@ -351,24 +349,6 @@ def test_auto_ml_multiple_outputs(auto_ml_multiple_outputs): assert built.dump()['outputs'] == [z.dump(), y.dump()] -def test_auto_ml_deprecated_training_data(auto_ml): - with pytest.deprecated_call(): - pred = AutoMLPredictor( - name='AutoML Predictor', - description='Predicts z from inputs w and x', - inputs=auto_ml.inputs, - outputs=auto_ml.outputs, - training_data=[GemTableDataSource(table_id=uuid.uuid4(), table_version=1)] - ) - - new_training_data = [GemTableDataSource(table_id=uuid.uuid4(), table_version=2)] - with pytest.deprecated_call(): - pred.training_data = new_training_data - - with pytest.deprecated_call(): - assert pred.training_data == new_training_data - - def test_ing_to_formulation_initialization(ing_to_formulation_predictor): """Make sure the correct fields go to the correct places for an ingredients to formulation predictor.""" assert ing_to_formulation_predictor.name == 'Ingredients to formulation predictor' @@ -403,28 +383,6 @@ def test_mean_property_round_robin(mean_property_predictor): assert len(cat_props) == 1 -def test_mean_property_training_data_deprecated(mean_property_predictor): - with pytest.deprecated_call(): - pred = MeanPropertyPredictor( - name='Mean property predictor', - description='Computes mean ingredient properties', - input_descriptor=mean_property_predictor.input_descriptor, - properties=mean_property_predictor.properties, - p=2.5, - impute_properties=True, - default_properties=mean_property_predictor.default_properties, - label=mean_property_predictor.label, - training_data=[GemTableDataSource(table_id=uuid.uuid4(), table_version=1)] - ) - - new_training_data = [GemTableDataSource(table_id=uuid.uuid4(), table_version=2)] - with pytest.deprecated_call(): - pred.training_data = new_training_data - - with pytest.deprecated_call(): - assert pred.training_data == new_training_data - - def test_label_fractions_property_initialization(label_fractions_predictor): """Make sure the correct fields go to the correct places for a label fraction predictor.""" assert label_fractions_predictor.name == 'Label fractions predictor' @@ -443,22 +401,6 @@ def test_simple_mixture_predictor_initialization(simple_mixture_predictor): assert str(simple_mixture_predictor) == expected_str -def test_simplex_mixture_training_data_deprecated(): - with pytest.deprecated_call(): - pred = SimpleMixturePredictor( - name='Simple mixture predictor', - description='Computes mean ingredient properties', - training_data=[GemTableDataSource(table_id=uuid.uuid4(), table_version=1)] - ) - - new_training_data = [GemTableDataSource(table_id=uuid.uuid4(), table_version=2)] - with pytest.deprecated_call(): - pred.training_data = new_training_data - - with pytest.deprecated_call(): - assert pred.training_data == new_training_data - - def test_ingredient_fractions_property_initialization(ingredient_fractions_predictor): """Make sure the correct fields go to the correct places for an ingredient fractions predictor.""" assert ingredient_fractions_predictor.name == 'Ingredient fractions predictor' diff --git a/tests/informatics/workflows/test_predictor_evaluation_workflow.py b/tests/informatics/workflows/test_predictor_evaluation_workflow.py deleted file mode 100644 index eee00a1cc..000000000 --- a/tests/informatics/workflows/test_predictor_evaluation_workflow.py +++ /dev/null @@ -1,40 +0,0 @@ -import pytest -import uuid - -from citrine.informatics.data_sources import GemTableDataSource -from citrine.informatics.predictor_evaluator import HoldoutSetEvaluator, CrossValidationEvaluator, PredictorEvaluator -from citrine.informatics.workflows import PredictorEvaluationWorkflow - - -@pytest.fixture() -def pew(): - data_source = GemTableDataSource(table_id=uuid.uuid4(), table_version=3) - evaluator1 = CrossValidationEvaluator(name="test CV", responses={"foo"}) - evaluator2 = HoldoutSetEvaluator(name="test holdout", responses={"foo"}, data_source=data_source) - pew = PredictorEvaluationWorkflow( - name="Test", - description="TestWorkflow", - evaluators=[evaluator1, evaluator2] - ) - return pew - - -def test_round_robin(pew): - dumped = pew.dump() - assert dumped["name"] == "Test" - assert dumped["description"] == "TestWorkflow" - assert PredictorEvaluator.build(dumped["evaluators"][0]).name == pew.evaluators[0].name - assert PredictorEvaluator.build(dumped["evaluators"][1]).name == pew.evaluators[1].name - - -def test_print(pew): - assert "PredictorEvaluationWorkflow" in str(pew) - - -def test_execution_error(pew): - with pytest.raises(AttributeError): - pew.executions - - pew.project_id = "foo" - with pytest.deprecated_call(): - assert pew.executions.project_id == "foo" diff --git a/tests/resources/test_data_concepts.py b/tests/resources/test_data_concepts.py index d9c359550..60a4af9a3 100644 --- a/tests/resources/test_data_concepts.py +++ b/tests/resources/test_data_concepts.py @@ -30,16 +30,6 @@ def run_noop_gemd_relation_search_test(search_for, search_with, collection, sear params={"dataset_id": str(collection.dataset_id), "forward": True, "ascending": True, "per_page": per_page} ) -def test_deprication_of_positional_arguments(): - session = FakeSession() - team_id = UUID('6b608f78-e341-422c-8076-35adc8828000') - check_project = {'project': {'team': {'id': team_id}}} - session.set_response(check_project) - with pytest.deprecated_call(): - ProcessSpecCollection(uuid4(), uuid4(), session) - with pytest.raises(TypeError): - ProcessSpecCollection(project_id=uuid4(), dataset_id=uuid4(), session=None) - def test_assign_audit_info(): """Test that audit_info can be injected with build but not set""" diff --git a/tests/resources/test_dataset.py b/tests/resources/test_dataset.py index 83dad4842..2a3c6a73c 100644 --- a/tests/resources/test_dataset.py +++ b/tests/resources/test_dataset.py @@ -63,15 +63,6 @@ def dataset(): return dataset -def test_deprecation_of_positional_arguments(session): - team_id = UUID('6b608f78-e341-422c-8076-35adc8828000') - check_project = {'project': {'team': {'id': team_id}}} - session.set_response(check_project) - with pytest.deprecated_call(): - dset = DatasetCollection(uuid4(), session) - with pytest.raises(TypeError): - dset = DatasetCollection(project_id=uuid4(), session=None) - def test_register_dataset(collection, session): # Given name = 'Test Dataset' diff --git a/tests/resources/test_file_link.py b/tests/resources/test_file_link.py index 338559e97..ecdd6726e 100644 --- a/tests/resources/test_file_link.py +++ b/tests/resources/test_file_link.py @@ -97,17 +97,6 @@ def uploader() -> _Uploader: """An _Uploader object with all of its fields filled in.""" return _UploaderFactory() -def test_deprecation_of_positional_arguments(session): - team_id = UUID('6b608f78-e341-422c-8076-35adc8828000') - check_project = {'project': {'team': {'id': team_id}}} - session.set_response(check_project) - with pytest.deprecated_call(): - _ = FileCollection(uuid4(), uuid4(), session) - with pytest.raises(TypeError): - _ = FileCollection(project_id=uuid4(), dataset_id=uuid4(), session=None) - with pytest.raises(TypeError): - _ = FileCollection(project_id=uuid4(), dataset_id=None, session=session) - def test_delete(collection: FileCollection, session): """Test that deletion calls the expected endpoint and checks the url structure.""" # Given @@ -568,12 +557,6 @@ def test_ingest(collection: FileCollection, session): with pytest.raises(ValueError): collection.ingest([good_file1], build_table=True) - session.set_responses(ingest_files_resp, job_id_resp, job_status_resp, ingest_status_resp) - coll_with_project_id = FileCollection(team_id=uuid4(), dataset_id=uuid4(), session=session) - coll_with_project_id.project_id = uuid4() - with pytest.deprecated_call(): - coll_with_project_id.ingest([good_file1], build_table=True) - def test_ingest_with_upload(collection, monkeypatch, tmp_path, session): """Test more advanced workflows, patching to avoid unnecessary complexity.""" diff --git a/tests/resources/test_gemd_resource.py b/tests/resources/test_gemd_resource.py index 780aa30c9..8b68ce092 100644 --- a/tests/resources/test_gemd_resource.py +++ b/tests/resources/test_gemd_resource.py @@ -68,13 +68,6 @@ def test_invalid_collection_construction(): dataset_id=UUID('8da51e93-8b55-4dd3-8489-af8f65d4ad9a'), session=session) -def test_deprecation_of_positional_arguments(session): - team_id = UUID('6b608f78-e341-422c-8076-35adc8828000') - check_project = {'project': {'team': {'id': team_id}}} - session.set_response(check_project) - with pytest.deprecated_call(): - fcol = GEMDResourceCollection(uuid4(), uuid4(), session) - def sample_gems(nsamples, **kwargs): factories = [MaterialRunDataFactory, MaterialSpecDataFactory] return [random.choice(factories)(**kwargs) for _ in range(nsamples)] diff --git a/tests/resources/test_ingestion.py b/tests/resources/test_ingestion.py index 5b3f791f0..2205fcd72 100644 --- a/tests/resources/test_ingestion.py +++ b/tests/resources/test_ingestion.py @@ -35,16 +35,6 @@ def dataset(session: Session): return dataset -@pytest.fixture -def deprecated_dataset(session: Session): - deprecated_dataset = DatasetFactory(name='Test Dataset') - deprecated_dataset.uid = uuid4() - deprecated_dataset.session = session - deprecated_dataset.project_id = uuid4() - - return deprecated_dataset - - @pytest.fixture def collection(dataset) -> IngestionCollection: return dataset.ingestions @@ -81,16 +71,6 @@ def status() -> IngestionStatus: }) -def test_create_deprecated_collection(session, deprecated_dataset): - check_project = {'project': {'team': {'id': str(uuid4())}}} - session.set_response(check_project) - with pytest.deprecated_call(): - ingestions = deprecated_dataset.ingestions - - assert session.calls == [FakeCall(method="GET", path=f'projects/{ingestions.project_id}')] - assert ingestions._path_template == f'projects/{ingestions.project_id}/ingestions' - - def test_not_implementeds(collection): """Test that unimplemented methods are still that.""" with pytest.raises(NotImplementedError): @@ -106,18 +86,6 @@ def test_not_implementeds(collection): collection.list() -def test_deprecation_of_positional_arguments(session): - team_id = UUID('6b608f78-e341-422c-8076-35adc8828000') - check_project = {'project': {'team': {'id': team_id}}} - session.set_response(check_project) - with pytest.deprecated_call(): - IngestionCollection(uuid4(), uuid4(), session) - with pytest.raises(TypeError): - IngestionCollection(project_id=uuid4(), dataset_id=uuid4(), session=None) - with pytest.raises(TypeError): - IngestionCollection(project_id=uuid4(), dataset_id=None, session=session) - - def test_poll_for_job_completion_signature(ingest, operation, status, monkeypatch): """Test calls on polling.""" @@ -267,7 +235,6 @@ def _mock_poll_for_job_completion(**_): def test_ingestion_with_table_build(session: FakeSession, ingest: Ingestion, dataset: Dataset, - deprecated_dataset: Dataset, file_link: FileLink): # build_objects_async will always approve, if we get that far session.set_responses(JobSubmissionResponseDataFactory()) @@ -275,15 +242,6 @@ def test_ingestion_with_table_build(session: FakeSession, with pytest.raises(ValueError): ingest.build_objects_async(build_table=True) - with pytest.deprecated_call(): - ingest.project_id = uuid4() - with pytest.deprecated_call(): - assert ingest.project_id is not None - with pytest.deprecated_call(): - ingest.build_objects_async(build_table=True) - with pytest.deprecated_call(): - ingest.project_id = None - project_uuid = uuid4() project = Project("Testing", session=session, team_id=dataset.team_id) project.uid = project_uuid diff --git a/tests/resources/test_ingredient_run.py b/tests/resources/test_ingredient_run.py index ae817c898..4217cc515 100644 --- a/tests/resources/test_ingredient_run.py +++ b/tests/resources/test_ingredient_run.py @@ -21,20 +21,6 @@ def collection(session) -> IngredientRunCollection: ) -def test_create_deprecated_collection(session): - project_id = '6b608f78-e341-422c-8076-35adc8828545' - session.set_response({'project': {'team': {'id': UUID("6b608f78-e341-422c-8076-35adc8828000")}}}) - - with pytest.deprecated_call(): - IngredientRunCollection( - dataset_id=UUID('8da51e93-8b55-4dd3-8489-af8f65d4ad9a'), - session=session, - project_id=UUID(project_id) - ) - - assert session.calls == [FakeCall(method="GET", path=f'projects/{project_id}')] - - def test_list_by_spec(collection: IngredientRunCollection): run_noop_gemd_relation_search_test( search_for='ingredient-runs', diff --git a/tests/resources/test_ingredient_spec.py b/tests/resources/test_ingredient_spec.py index 52a4b4e21..8301c7471 100644 --- a/tests/resources/test_ingredient_spec.py +++ b/tests/resources/test_ingredient_spec.py @@ -24,19 +24,6 @@ def collection(session) -> IngredientSpecCollection: session=session) -def test_create_deprecated_collection(session): - project_id = '6b608f78-e341-422c-8076-35adc8828545' - session.set_response({'project': {'team': {'id': UUID("6b608f78-e341-422c-8076-35adc8828000")}}}) - - with pytest.deprecated_call(): - IngredientSpecCollection( - project_id=UUID(project_id), - dataset_id=UUID('8da51e93-8b55-4dd3-8489-af8f65d4ad9a'), - session=session) - - assert session.calls == [FakeCall(method="GET", path=f'projects/{project_id}')] - - def test_list_by_material(collection: IngredientSpecCollection): run_noop_gemd_relation_search_test( search_for='ingredient-specs', diff --git a/tests/resources/test_material_run.py b/tests/resources/test_material_run.py index 1c24e4bcd..96d10ca11 100644 --- a/tests/resources/test_material_run.py +++ b/tests/resources/test_material_run.py @@ -39,16 +39,6 @@ def collection(session) -> MaterialRunCollection: session=session, team_id = UUID('6b608f78-e341-422c-8076-35adc8828000')) -def test_deprecated_collection_construction(session): - with pytest.deprecated_call(): - team_id = UUID('6b608f78-e341-422c-8076-35adc8828000') - check_project = {'project': {'team': {'id': team_id}}} - session.set_response(check_project) - mr = MaterialRunCollection( - dataset_id=UUID('8da51e93-8b55-4dd3-8489-af8f65d4ad9a'), - session=session, - project_id=UUID('6b608f78-e341-422c-8076-35adc8828545')) - def test_invalid_collection_construction(): with pytest.raises(TypeError): mr = MaterialRunCollection(dataset_id=UUID('8da51e93-8b55-4dd3-8489-af8f65d4ad9a'), diff --git a/tests/resources/test_material_spec.py b/tests/resources/test_material_spec.py index e0609eeba..d6002b70d 100644 --- a/tests/resources/test_material_spec.py +++ b/tests/resources/test_material_spec.py @@ -23,19 +23,6 @@ def collection(session) -> MaterialSpecCollection: session=session) -def test_create_deprecated_collection(session): - project_id = '6b608f78-e341-422c-8076-35adc8828545' - session.set_response({'project': {'team': {'id': UUID("6b608f78-e341-422c-8076-35adc8828000")}}}) - - with pytest.deprecated_call(): - MaterialSpecCollection( - project_id=UUID(project_id), - dataset_id=UUID('8da51e93-8b55-4dd3-8489-af8f65d4ad9a'), - session=session) - - assert session.calls == [FakeCall(method="GET", path=f'projects/{project_id}')] - - def test_list_by_template(collection): run_noop_gemd_relation_search_test( search_for='material-specs', diff --git a/tests/resources/test_measurement_run.py b/tests/resources/test_measurement_run.py index 9df202700..eb94f6aaa 100644 --- a/tests/resources/test_measurement_run.py +++ b/tests/resources/test_measurement_run.py @@ -20,19 +20,6 @@ def collection(session) -> MeasurementRunCollection: session=session) -def test_create_deprecated_collection(session): - project_id = '6b608f78-e341-422c-8076-35adc8828545' - session.set_response({'project': {'team': {'id': UUID("6b608f78-e341-422c-8076-35adc8828000")}}}) - - with pytest.deprecated_call(): - MeasurementRunCollection( - project_id=UUID(project_id), - dataset_id=UUID('8da51e93-8b55-4dd3-8489-af8f65d4ad9a'), - session=session) - - assert session.calls == [FakeCall(method="GET", path=f'projects/{project_id}')] - - def test_list_by_template(collection: MeasurementRunCollection): run_noop_gemd_relation_search_test( search_for='measurement-runs', diff --git a/tests/resources/test_measurement_spec.py b/tests/resources/test_measurement_spec.py index 716da9ee6..abe8b1b56 100644 --- a/tests/resources/test_measurement_spec.py +++ b/tests/resources/test_measurement_spec.py @@ -22,19 +22,6 @@ def collection(session) -> MeasurementSpecCollection: session=session) -def test_create_deprecated_collection(session): - project_id = '6b608f78-e341-422c-8076-35adc8828545' - session.set_response({'project': {'team': {'id': UUID("6b608f78-e341-422c-8076-35adc8828000")}}}) - - with pytest.deprecated_call(): - MeasurementSpecCollection( - project_id=UUID(project_id), - dataset_id=UUID('8da51e93-8b55-4dd3-8489-af8f65d4ad9a'), - session=session) - - assert session.calls == [FakeCall(method="GET", path=f'projects/{project_id}')] - - def test_list_by_template(collection: MeasurementSpecCollection): run_noop_gemd_relation_search_test( search_for='measurement-specs', diff --git a/tests/resources/test_predictor_evaluation_executions.py b/tests/resources/test_predictor_evaluation_executions.py deleted file mode 100644 index 53c548282..000000000 --- a/tests/resources/test_predictor_evaluation_executions.py +++ /dev/null @@ -1,174 +0,0 @@ -import random -import uuid - -import pytest - -from citrine._rest.resource import PredictorRef -from citrine.informatics.executions.predictor_evaluation_execution import PredictorEvaluationExecution -from citrine.informatics.predictor_evaluation_result import PredictorEvaluationResult -from citrine.resources.predictor_evaluation_execution import PredictorEvaluationExecutionCollection -from tests.utils.session import FakeSession, FakeCall - - -@pytest.fixture -def session() -> FakeSession: - return FakeSession() - - -@pytest.fixture -def collection(session) -> PredictorEvaluationExecutionCollection: - with pytest.deprecated_call(): - return PredictorEvaluationExecutionCollection( - project_id=uuid.uuid4(), - workflow_id=uuid.uuid4(), - session=session, - ) - - -@pytest.fixture -def workflow_execution(collection: PredictorEvaluationExecutionCollection, predictor_evaluation_execution_dict) -> PredictorEvaluationExecution: - return collection.build(predictor_evaluation_execution_dict) - - -def test_basic_methods(workflow_execution, collection): - assert "PredictorEvaluationExecution" in str(workflow_execution) - - with pytest.raises(TypeError): - workflow_execution[12] - - assert "Example evaluator" in list(iter(workflow_execution)) - - with pytest.deprecated_call(): - with pytest.raises(NotImplementedError): - collection.register(workflow_execution) - - with pytest.deprecated_call(): - with pytest.raises(NotImplementedError): - collection.update(workflow_execution) - - -def test_build_new_execution(collection, predictor_evaluation_execution_dict): - # Given - workflow_execution_id = uuid.uuid4() - build_data = predictor_evaluation_execution_dict.copy() - build_data["id"] = str(workflow_execution_id) - build_data["workflow_id"] = str(collection.workflow_id) - - # When - execution: PredictorEvaluationExecution = collection.build(build_data) - - # Then - assert execution.uid == workflow_execution_id - assert execution.project_id == collection.project_id - assert execution.workflow_id == collection.workflow_id - assert execution._session == collection.session - assert execution.in_progress() and not execution.succeeded() and not execution.failed() - assert execution.status_detail - - -def test_workflow_execution_results(workflow_execution: PredictorEvaluationExecution, session, - example_cv_result_dict): - # Given - session.set_response(example_cv_result_dict) - - # When - results = workflow_execution["Example Evaluator"] - - # Then - assert results.evaluator == PredictorEvaluationResult.build(example_cv_result_dict).evaluator - expected_path = '/projects/{}/predictor-evaluation-executions/{}/results'.format( - workflow_execution.project_id, - workflow_execution.uid, - ) - assert session.last_call == FakeCall(method='GET', path=expected_path, params={"evaluator_name": "Example Evaluator"}) - - -def test_trigger_workflow_execution(collection: PredictorEvaluationExecutionCollection, predictor_evaluation_execution_dict, session): - # Given - predictor_id = uuid.uuid4() - random_state = 9325 - session.set_response(predictor_evaluation_execution_dict) - - # When - with pytest.deprecated_call(): - actual_execution = collection.trigger(predictor_id, random_state=random_state) - - # Then - assert str(actual_execution.uid) == predictor_evaluation_execution_dict["id"] - expected_path = '/projects/{}/predictor-evaluation-workflows/{}/executions'.format( - collection.project_id, - collection.workflow_id, - ) - assert session.last_call == FakeCall( - method='POST', - path=expected_path, - json=PredictorRef(predictor_id).dump(), - params={"random_state": random_state} - ) - - -def test_trigger_workflow_execution_with_version(collection: PredictorEvaluationExecutionCollection, predictor_evaluation_execution_dict, session): - # Given - predictor_id = uuid.uuid4() - predictor_version = random.randint(1, 10) - session.set_response(predictor_evaluation_execution_dict) - - # When - with pytest.deprecated_call(): - actual_execution = collection.trigger(predictor_id, predictor_version=predictor_version) - - # Then - assert str(actual_execution.uid) == predictor_evaluation_execution_dict["id"] - expected_path = '/projects/{}/predictor-evaluation-workflows/{}/executions'.format( - collection.project_id, - collection.workflow_id, - ) - assert session.last_call == FakeCall( - method='POST', - path=expected_path, - json=PredictorRef(predictor_id, predictor_version).dump() - ) - - -@pytest.mark.parametrize("predictor_version", (2, "1", "latest", None)) -def test_list(collection: PredictorEvaluationExecutionCollection, session, predictor_version): - session.set_response({"page": 1, "per_page": 4, "next": "", "response": []}) - predictor_id = uuid.uuid4() - with pytest.deprecated_call(): - lst = list(collection.list(per_page=4, predictor_id=predictor_id, predictor_version=predictor_version)) - assert not lst - - expected_path = '/projects/{}/predictor-evaluation-executions'.format(collection.project_id) - expected_payload = {"per_page": 4, "predictor_id": str(predictor_id), "workflow_id": str(collection.workflow_id), 'page': 1} - if predictor_version is not None: - expected_payload["predictor_version"] = predictor_version - assert session.last_call == FakeCall(method='GET', path=expected_path, params=expected_payload) - - -def test_archive(workflow_execution, collection): - with pytest.deprecated_call(): - collection.archive(workflow_execution.uid) - expected_path = '/projects/{}/predictor-evaluation-executions/archive'.format(collection.project_id) - assert collection.session.last_call == FakeCall(method='PUT', path=expected_path, json={"module_uid": str(workflow_execution.uid)}) - - -def test_restore(workflow_execution, collection): - with pytest.deprecated_call(): - collection.restore(workflow_execution.uid) - expected_path = '/projects/{}/predictor-evaluation-executions/restore'.format(collection.project_id) - assert collection.session.last_call == FakeCall(method='PUT', path=expected_path, json={"module_uid": str(workflow_execution.uid)}) - - -def test_delete(collection): - with pytest.deprecated_call(): - with pytest.raises(NotImplementedError): - collection.delete(uuid.uuid4()) - -def test_get(predictor_evaluation_execution_dict, workflow_execution, collection): - collection.session.set_response(predictor_evaluation_execution_dict) - - with pytest.deprecated_call(): - execution = collection.get(workflow_execution.uid) - - expected_path = f'/projects/{collection.project_id}/predictor-evaluation-executions/{workflow_execution.uid}' - assert collection.session.last_call == FakeCall(method='GET', path=expected_path) diff --git a/tests/resources/test_predictor_evaluation_workflows.py b/tests/resources/test_predictor_evaluation_workflows.py deleted file mode 100644 index d231a583c..000000000 --- a/tests/resources/test_predictor_evaluation_workflows.py +++ /dev/null @@ -1,117 +0,0 @@ -from typing import Optional, Union -import uuid - -import pytest - -from citrine.informatics.workflows import PredictorEvaluationWorkflow -from citrine.resources.predictor_evaluation_workflow import PredictorEvaluationWorkflowCollection -from tests.utils.session import FakeSession, FakeCall - - -@pytest.fixture -def session() -> FakeSession: - return FakeSession() - - -@pytest.fixture -def collection(session) -> PredictorEvaluationWorkflowCollection: - with pytest.deprecated_call(): - return PredictorEvaluationWorkflowCollection( - project_id=uuid.uuid4(), - session=session, - ) - - -@pytest.fixture -def workflow(collection: PredictorEvaluationWorkflowCollection, - predictor_evaluation_workflow_dict) -> PredictorEvaluationWorkflow: - return collection.build(predictor_evaluation_workflow_dict) - - -def test_basic_methods(workflow, collection): - assert "PredictorEvaluationWorkflow" in str(workflow) - assert workflow.evaluators[0].name == "Example evaluator" - - -def test_archive(workflow, collection): - with pytest.deprecated_call(): - collection.archive(workflow.uid) - expected_path = '/projects/{}/predictor-evaluation-workflows/archive'.format(collection.project_id) - assert collection.session.last_call == FakeCall(method='PUT', path=expected_path, - json={"module_uid": str(workflow.uid)}) - - -def test_restore(workflow, collection): - with pytest.deprecated_call(): - collection.restore(workflow.uid) - expected_path = '/projects/{}/predictor-evaluation-workflows/restore'.format(collection.project_id) - assert collection.session.last_call == FakeCall(method='PUT', path=expected_path, - json={"module_uid": str(workflow.uid)}) - - -def test_delete(collection): - with pytest.deprecated_call(): - with pytest.raises(NotImplementedError): - collection.delete(uuid.uuid4()) - - -@pytest.mark.parametrize("predictor_version", (2, "1", "latest", None)) -def test_create_default(predictor_evaluation_workflow_dict: dict, - predictor_version: Optional[Union[int, str]], - workflow: PredictorEvaluationWorkflow): - project_id = uuid.uuid4() - predictor_id = uuid.uuid4() - - session = FakeSession() - session.set_response(predictor_evaluation_workflow_dict) - with pytest.deprecated_call(): - collection = PredictorEvaluationWorkflowCollection( - project_id=project_id, - session=session - ) - with pytest.deprecated_call(): - default_workflow = collection.create_default(predictor_id=predictor_id, predictor_version=predictor_version) - - url = f'/projects/{collection.project_id}/predictor-evaluation-workflows/default' - - expected_payload = {"predictor_id": str(predictor_id)} - if predictor_version is not None: - expected_payload["predictor_version"] = predictor_version - assert session.calls == [FakeCall(method="POST", path=url, json=expected_payload)] - assert default_workflow.dump() == workflow.dump() - -def test_register(predictor_evaluation_workflow_dict, workflow, collection): - collection.session.set_response(predictor_evaluation_workflow_dict) - - with pytest.deprecated_call(): - collection.register(workflow) - - expected_path = f'/projects/{collection.project_id}/predictor-evaluation-workflows' - assert collection.session.last_call == FakeCall(method='POST', path=expected_path, json=workflow.dump()) - -def test_list(predictor_evaluation_workflow_dict, workflow, collection): - collection.session.set_response({"page": 1, "per_page": 4, "next": "", "response": [predictor_evaluation_workflow_dict]}) - - with pytest.deprecated_call(): - list(collection.list(per_page=20)) - - expected_path = f'/projects/{collection.project_id}/predictor-evaluation-workflows' - assert collection.session.last_call == FakeCall(method='GET', path=expected_path, params={"per_page": 20, "page": 1}) - -def test_update(predictor_evaluation_workflow_dict, workflow, collection): - collection.session.set_response(predictor_evaluation_workflow_dict) - - with pytest.deprecated_call(): - collection.update(workflow) - - expected_path = f'/projects/{collection.project_id}/predictor-evaluation-workflows/{workflow.uid}' - assert collection.session.last_call == FakeCall(method='PUT', path=expected_path, json=workflow.dump()) - -def test_get(predictor_evaluation_workflow_dict, workflow, collection): - collection.session.set_response(predictor_evaluation_workflow_dict) - - with pytest.deprecated_call(): - collection.get(workflow.uid) - - expected_path = f'/projects/{collection.project_id}/predictor-evaluation-workflows/{workflow.uid}' - assert collection.session.last_call == FakeCall(method='GET', path=expected_path) diff --git a/tests/resources/test_process_run.py b/tests/resources/test_process_run.py index 3dc6e04c5..58fb8c1fd 100644 --- a/tests/resources/test_process_run.py +++ b/tests/resources/test_process_run.py @@ -20,19 +20,6 @@ def collection(session) -> ProcessRunCollection: session=session) -def test_create_deprecated_collection(session): - project_id = '6b608f78-e341-422c-8076-35adc8828545' - session.set_response({'project': {'team': {'id': UUID("6b608f78-e341-422c-8076-35adc8828000")}}}) - - with pytest.deprecated_call(): - ProcessRunCollection( - project_id=UUID(project_id), - dataset_id=UUID('8da51e93-8b55-4dd3-8489-af8f65d4ad9a'), - session=session) - - assert session.calls == [FakeCall(method="GET", path=f'projects/{project_id}')] - - def test_list_by_spec(collection: ProcessRunCollection): run_noop_gemd_relation_search_test( search_for='process-runs', diff --git a/tests/resources/test_process_spec.py b/tests/resources/test_process_spec.py index fce60075b..f997a8129 100644 --- a/tests/resources/test_process_spec.py +++ b/tests/resources/test_process_spec.py @@ -22,19 +22,6 @@ def collection(session) -> ProcessSpecCollection: session=session) -def test_create_deprecated_collection(session): - project_id = '6b608f78-e341-422c-8076-35adc8828545' - session.set_response({'project': {'team': {'id': UUID("6b608f78-e341-422c-8076-35adc8828000")}}}) - - with pytest.deprecated_call(): - ProcessSpecCollection( - project_id=UUID(project_id), - dataset_id=UUID('8da51e93-8b55-4dd3-8489-af8f65d4ad9a'), - session=session) - - assert session.calls == [FakeCall(method="GET", path=f'projects/{project_id}')] - - def test_list_by_template(collection: ProcessSpecCollection): run_noop_gemd_relation_search_test( search_for='process-specs', diff --git a/tests/resources/test_project.py b/tests/resources/test_project.py index 0a1905d74..162931fc3 100644 --- a/tests/resources/test_project.py +++ b/tests/resources/test_project.py @@ -53,12 +53,6 @@ def collection(session) -> ProjectCollection: return ProjectCollection(session, team_id=uuid.uuid4()) -@pytest.fixture -def datasets(project) -> DatasetCollection: - with pytest.deprecated_call(): - return project.datasets - - def test_get_team_id_from_project(session): team_id = uuid.UUID('6b608f78-e341-422c-8076-35adc8828000') check_project = {'project': {'team': {'id': team_id}}} @@ -87,27 +81,13 @@ def test_publish_resource(project, session): assert expected_call == session.last_call -def test_publish_resource_deprecated(project, datasets, session): - dataset_id = str(uuid.uuid4()) - dataset = datasets.build(dict( - id=dataset_id, - name="public dataset", summary="test", description="test" - )) - with pytest.deprecated_call(): +def test_publish_resource_dataset(project, session): + dataset = Dataset("public dataset", summary="test", description="test") + with pytest.raises(ValueError): assert project.publish(resource=dataset) - assert 1 == session.num_calls - expected_call = FakeCall( - method='POST', - path=f'/projects/{project.uid}/published-resources/DATASET/batch-publish', - json={ - 'ids': [str(dataset.uid)] - } - ) - assert expected_call == session.last_call - -def test_pull_in_resource(project, datasets, session): +def test_pull_in_resource(project, session): predictor = GraphPredictor(name="foo", description="foo", predictors=[]) predictor.uid = uuid.uuid4() assert project.pull_in_resource(resource=predictor) @@ -123,27 +103,13 @@ def test_pull_in_resource(project, datasets, session): assert expected_call == session.last_call -def test_pull_in_resource_deprecated(project, datasets, session): - dataset_id = str(uuid.uuid4()) - dataset = datasets.build(dict( - id=dataset_id, - name="public dataset", summary="test", description="test" - )) - with pytest.deprecated_call(): +def test_pull_in_resource_dataset(project, session): + dataset = Dataset("public dataset", summary="test", description="test") + with pytest.raises(ValueError): assert project.pull_in_resource(resource=dataset) - assert 1 == session.num_calls - expected_call = FakeCall( - method='POST', - path=f'/teams/{project.team_id}/projects/{project.uid}/outside-resources/DATASET/batch-pull-in', - json={ - 'ids': [str(dataset.uid)] - } - ) - assert expected_call == session.last_call - -def test_un_publish_resource(project, datasets, session): +def test_un_publish_resource(project, session): predictor = GraphPredictor(name="foo", description="foo", predictors=[]) predictor.uid = uuid.uuid4() assert project.un_publish(resource=predictor) @@ -159,137 +125,11 @@ def test_un_publish_resource(project, datasets, session): assert expected_call == session.last_call -def test_un_publish_resource_deprecated(project, datasets, session): - dataset_id = str(uuid.uuid4()) - dataset = datasets.build(dict( - id=dataset_id, - name="public dataset", summary="test", description="test" - )) - with pytest.deprecated_call(): +def test_un_publish_resource_dataset(project, session): + dataset = Dataset("public dataset", summary="test", description="test") + with pytest.raises(ValueError): assert project.un_publish(resource=dataset) - assert 1 == session.num_calls - expected_call = FakeCall( - method='POST', - path=f'/projects/{project.uid}/published-resources/DATASET/batch-un-publish', - json={ - 'ids': [str(dataset.uid)] - } - ) - assert expected_call == session.last_call - - -def test_datasets_get_project_id(project): - with pytest.deprecated_call(): - collection = project.datasets - - assert project.uid == collection.project_id - - -def test_property_templates_get_project_id(project): - with pytest.deprecated_call(): - collection = project.property_templates - - assert project.uid == collection.project_id - - -def test_condition_templates_get_project_id(project): - with pytest.deprecated_call(): - collection = project.condition_templates - - assert project.uid == collection.project_id - - -def test_parameter_templates_get_project_id(project): - with pytest.deprecated_call(): - collection = project.parameter_templates - - assert project.uid == collection.project_id - - -def test_material_templates_get_project_id(project): - with pytest.deprecated_call(): - collection = project.material_templates - - assert project.uid == collection.project_id - - -def test_measurement_templates_get_project_id(project): - with pytest.deprecated_call(): - collection = project.measurement_templates - - assert project.uid == collection.project_id - - -def test_process_templates_get_project_id(project): - with pytest.deprecated_call(): - collection = project.process_templates - - assert project.uid == collection.project_id - - -def test_process_runs_get_project_id(project): - with pytest.deprecated_call(): - collection = project.process_runs - - assert project.uid == collection.project_id - - -def test_measurement_runs_get_project_id(project): - with pytest.deprecated_call(): - collection = project.measurement_runs - - assert project.uid == collection.project_id - - -def test_material_runs_get_project_id(project): - with pytest.deprecated_call(): - collection = project.material_runs - - assert project.uid == collection.project_id - - -def test_ingredient_runs_get_project_id(project): - with pytest.deprecated_call(): - collection = project.ingredient_runs - - assert project.uid == collection.project_id - - -def test_process_specs_get_project_id(project): - with pytest.deprecated_call(): - collection = project.process_specs - - assert project.uid == collection.project_id - - -def test_measurement_specs_get_project_id(project): - with pytest.deprecated_call(): - collection = project.measurement_specs - - assert project.uid == collection.project_id - - -def test_material_specs_get_project_id(project): - with pytest.deprecated_call(): - collection = project.material_specs - - assert project.uid == collection.project_id - - -def test_ingredient_specs_get_project_id(project): - with pytest.deprecated_call(): - collection = project.ingredient_specs - - assert project.uid == collection.project_id - - -def test_gemd_resource_get_project_id(project): - with pytest.deprecated_call(): - collection = project.gemd - - assert project.uid == collection.project_id - def test_design_spaces_get_project_id(project): assert project.uid == project.design_spaces.project_id @@ -303,20 +143,6 @@ def test_predictors_get_project_id(project): assert project.uid == project.predictors.project_id -def test_pe_workflows_get_project_id(project): - with pytest.deprecated_call(): - assert project.uid == project.predictor_evaluation_workflows.project_id - - -def test_pe_executions_get_project_id(project): - with pytest.deprecated_call(): - assert project.uid == project.predictor_evaluation_executions.project_id - # The resulting collection cannot be used to trigger executions. - with pytest.deprecated_call(): - with pytest.raises(RuntimeError): - project.predictor_evaluation_executions.trigger(uuid.uuid4()) - - def test_predictor_evaluations_get_project_id(project): assert project.uid == project.predictor_evaluations.project_id @@ -677,138 +503,5 @@ def test_list_members(project, session): assert isinstance(members[0], TeamMember) -def test_project_batch_delete_no_errors(project, session): - job_resp = { - 'job_id': '1234' - } - - # Actual response-like data - note there is no 'failures' array within 'output' - successful_job_resp = { - 'job_type': 'batch_delete', - 'status': 'Success', - 'tasks': [ - { - "id": "7b6bafd9-f32a-4567-b54c-7ce594edc018", "task_type": "batch_delete", - "status": "Success", "dependencies": [] - } - ], - 'output': {} - } - - session.set_responses(job_resp, successful_job_resp) - - # When - with pytest.deprecated_call(): - del_resp = project.gemd_batch_delete([uuid.UUID('16fd2706-8baf-433b-82eb-8c7fada847da')]) - - # Then - assert len(del_resp) == 0 - - # When trying with entities - session.set_responses(job_resp, successful_job_resp) - entity = ProcessSpec(name="proc spec", uids={'id': '16fd2706-8baf-433b-82eb-8c7fada847da'}) - with pytest.deprecated_call(): - del_resp = project.gemd_batch_delete([entity]) - - # Then - assert len(del_resp) == 0 - - -def test_project_batch_delete(project, session): - job_resp = { - 'job_id': '1234' - } - - failures_escaped_json = json.dumps([ - { - "id": { - 'scope': 'somescope', - 'id': 'abcd-1234' - }, - 'cause': { - "code": 400, - "message": "", - "validation_errors": [ - { - "failure_message": "fail msg", - "failure_id": "identifier.coreid.missing" - } - ] - } - } - ]) - - failed_job_resp = { - 'job_type': 'batch_delete', - 'status': 'Success', - 'tasks': [], - 'output': { - 'failures': failures_escaped_json - } - } - - session.set_responses(job_resp, failed_job_resp, job_resp, failed_job_resp) - - # When - with pytest.deprecated_call(): - del_resp = project.gemd_batch_delete([uuid.UUID('16fd2706-8baf-433b-82eb-8c7fada847da')]) - - # Then - assert 2 == session.num_calls - - assert len(del_resp) == 1 - first_failure = del_resp[0] - - expected_api_error = ApiError.build({ - "code": "400", - "message": "", - "validation_errors": [{"failure_message": "fail msg", "failure_id": "identifier.coreid.missing"}] - }) - - assert first_failure[0] == LinkByUID('somescope', 'abcd-1234') - assert first_failure[1].dump() == expected_api_error.dump() - - # And again with tuples of (scope, id) - with pytest.deprecated_call(): - del_resp = project.gemd_batch_delete([LinkByUID('id', '16fd2706-8baf-433b-82eb-8c7fada847da')]) - assert len(del_resp) == 1 - first_failure = del_resp[0] - - assert first_failure[0] == LinkByUID('somescope', 'abcd-1234') - assert first_failure[1].dump() == expected_api_error.dump() - - -def test_batch_delete_bad_input(project): - with pytest.deprecated_call(): - with pytest.raises(TypeError): - project.gemd_batch_delete([True]) - - def test_project_tables(project): assert isinstance(project.tables, GemTableCollection) - - -def test_owned_dataset_ids(project, datasets): - # Create a set of datasets in the project - ids = {uuid.uuid4() for _ in range(5)} - for d_id in ids: - dataset = Dataset(name=f"Test Dataset - {d_id}", summary="Test Dataset", description="Test Dataset") - datasets.register(dataset) - - # Set the session response to have the list of dataset IDs - project.session.set_response({'ids': list(ids)}) - - # Fetch the list of UUID owned by the current project - with pytest.deprecated_call(): - owned_ids = project.owned_dataset_ids() - - # Let's mock our expected API call so we can compare and ensure that the one made is the same - expect_call = FakeCall(method='GET', - path='/DATASET/authorized-ids', - params={'userId': '', - 'domain': '/projects/16fd2706-8baf-433b-82eb-8c7fada847da', - 'action': 'WRITE'}) - # Compare our calls - assert expect_call == project.session.last_call - assert project.session.num_calls == len(ids) + 1 - assert ids == set(owned_ids) diff --git a/tests/resources/test_table_config.py b/tests/resources/test_table_config.py index 7be645f05..4e11ed504 100644 --- a/tests/resources/test_table_config.py +++ b/tests/resources/test_table_config.py @@ -66,27 +66,6 @@ def empty_defn() -> TableConfig: return TableConfig(name="empty", description="empty", datasets=[], rows=[], variables=[], columns=[]) -def test_deprecation_of_positional_arguments(session): - with pytest.deprecated_call(): - TableConfigCollection( - UUID('6b608f78-e341-422c-8076-35adc8828545'), - session, - team_id=UUID('6b608f78-e341-422c-8076-35adc8828545'), - ) - - with pytest.raises(TypeError): - TableConfigCollection( - team_id=UUID('6b608f78-e341-422c-8076-35adc8828545'), - session=session - ) - - with pytest.raises(TypeError): - TableConfigCollection( - team_id=UUID('6b608f78-e341-422c-8076-35adc8828545'), - project_id=UUID('6b608f78-e341-422c-8076-35adc8828545') - ) - - def test_get_table_config(collection, session): """Get table config, with or without version""" @@ -421,75 +400,6 @@ def test_add_columns(): assert "already used" in str(excinfo.value) -def test_add_all_ingredients_via_project_deprecated(session, project): - """Test the behavior of AraDefinition.add_all_ingredients.""" - # GIVEN - process_id = '3a308f78-e341-f39c-8076-35a2c88292ad' - process_name = 'mixing' - allowed_names = ["gold nanoparticles", "methanol", "acetone"] - process_link = LinkByUID('id', process_id) - session.set_response( - ProcessTemplate(process_name, uids={'id': process_id}, allowed_names=allowed_names).dump() - ) - - # WHEN we add all ingredients in a volume basis - empty = empty_defn() - with pytest.deprecated_call(): - def1 = empty.add_all_ingredients(process_template=process_link, project=project, - quantity_dimension=IngredientQuantityDimension.VOLUME) - def1.config_uid = uuid4() - - # THEN there should be 3 variables and columns for each name, one for id, quantity, and labels - assert len(def1.variables) == len(allowed_names) * 3 - assert len(def1.columns) == len(def1.variables) - for name in allowed_names: - assert next((var for var in def1.variables if name in var.headers - and isinstance(var, IngredientQuantityByProcessAndName)), None) is not None - assert next((var for var in def1.variables if name in var.headers - and isinstance(var, IngredientIdentifierByProcessTemplateAndName)), None) is not None - assert next((var for var in def1.variables if name in var.headers - and isinstance(var, IngredientLabelsSetByProcessAndName)), None) is not None - - session.set_response( - ProcessTemplate(process_name, uids={'id': process_id}, allowed_names=allowed_names).dump() - ) - # WHEN we add all ingredients to the same Table Config as absolute quantities - with pytest.deprecated_call(): - def2 = def1.add_all_ingredients(process_template=process_link, project=project, - quantity_dimension=IngredientQuantityDimension.ABSOLUTE, - unit='kg') - # THEN there should be 1 new variable for each name, corresponding to the quantity - # There is already a variable for id and labels - # There should be 2 new columns for each name, one for the quantity and one for the units - new_variables = def2.variables[len(def1.variables):] - new_columns = def2.columns[len(def1.columns):] - assert len(new_variables) == len(allowed_names) - assert len(new_columns) == len(allowed_names) * 2 - assert def2.config_uid == def1.config_uid - for name in allowed_names: - assert next((var for var in new_variables if name in var.headers - and isinstance(var, IngredientQuantityByProcessAndName)), None) is not None - - session.set_response( - ProcessTemplate(process_name, uids={'id': process_id}, allowed_names=allowed_names).dump() - ) - # WHEN we add all ingredients to the same Table Config in a volume basis - # THEN it raises an exception because these variables and columns already exist - with pytest.deprecated_call(): - with pytest.raises(ValueError): - def2.add_all_ingredients(process_template=process_link, project=project, - quantity_dimension=IngredientQuantityDimension.VOLUME) - - # If the process template has an empty allowed_names list then an error should be raised - session.set_response( - ProcessTemplate(process_name, uids={'id': process_id}).dump() - ) - with pytest.deprecated_call(): - with pytest.raises(RuntimeError): - empty_defn().add_all_ingredients(process_template=process_link, project=project, - quantity_dimension=IngredientQuantityDimension.VOLUME) - - def test_add_all_ingredients_via_team(session, team): """Test the behavior of AraDefinition.add_all_ingredients.""" # GIVEN @@ -563,129 +473,6 @@ def test_add_all_ingredients_no_principal(session): quantity_dimension=IngredientQuantityDimension.VOLUME) -def test_add_all_ingredients_in_output_via_project_deprecated(session, project): - """Test the behavior of TableConfig.add_all_ingredients_in_output.""" - # GIVEN - process1_id = '3a308f78-e341-f39c-8076-35a2c88292ad' - process1_name = 'mixing' - allowed_names1 = ["gold nanoparticles", "methanol", "acetone"] - process1_link = LinkByUID('id', process1_id) - - process2_id = '519ab440-fbda-4768-ad63-5e09b420285c' - process2_name = 'solvent_mixing' - allowed_names2 = ["methanol", "acetone", "ethanol", "water"] - process2_link = LinkByUID('id', process2_id) - - union_allowed_names = list(set(allowed_names1) | set(allowed_names2)) - - session.set_responses( - ProcessTemplate( - process1_name, - uids={'id': process1_id}, - allowed_names=allowed_names1 - ).dump(), - ProcessTemplate( - process2_name, - uids={'id': process2_id}, - allowed_names=allowed_names2 - ).dump() - ) - - # WHEN we add all ingredients in a volume basis - empty = empty_defn() - with pytest.deprecated_call(): - def1 = empty.add_all_ingredients_in_output( - process_templates=[process1_link, process2_link], - project=project, - quantity_dimension=IngredientQuantityDimension.VOLUME - ) - def1.config_uid = uuid4() - - # THEN there should be 3 variables and columns for each name, one for id, quantity, and labels - assert len(def1.variables) == len(union_allowed_names) * 3 - assert len(def1.columns) == len(def1.variables) - for name in union_allowed_names: - assert next((var for var in def1.variables if name in var.headers - and isinstance(var, IngredientQuantityInOutput)), None) is not None - assert next((var for var in def1.variables if name in var.headers - and isinstance(var, IngredientIdentifierInOutput)), None) is not None - assert next((var for var in def1.variables if name in var.headers - and isinstance(var, IngredientLabelsSetInOutput)), None) is not None - - session.set_responses( - ProcessTemplate( - process1_name, - uids={'id': process1_id}, - allowed_names=allowed_names1 - ).dump(), - ProcessTemplate( - process2_name, - uids={'id': process2_id}, - allowed_names=allowed_names2 - ).dump() - ) - # WHEN we add all ingredients to the same Table Config as absolute quantities - with pytest.deprecated_call(): - def2 = def1.add_all_ingredients_in_output( - process_templates=[process1_link, process2_link], - project=project, - quantity_dimension=IngredientQuantityDimension.ABSOLUTE, - unit='kg' - ) - # THEN there should be 1 new variable for each name, corresponding to the quantity - # There is already a variable for id and labels - # There should be 2 new columns for each name, one for the quantity and one for the units - new_variables = def2.variables[len(def1.variables):] - new_columns = def2.columns[len(def1.columns):] - assert len(new_variables) == len(union_allowed_names) - assert len(new_columns) == len(union_allowed_names) * 2 - assert def2.config_uid == def1.config_uid - for name in union_allowed_names: - assert next((var for var in new_variables if name in var.headers - and isinstance(var, IngredientQuantityInOutput)), None) is not None - - session.set_responses( - ProcessTemplate( - process1_name, - uids={'id': process1_id}, - allowed_names=allowed_names1 - ).dump(), - ProcessTemplate( - process2_name, - uids={'id': process2_id}, - allowed_names=allowed_names2 - ).dump() - ) - # WHEN we add all ingredients to the same Table Config in a volume basis - # THEN it raises an exception because these variables and columns already exist - with pytest.deprecated_call(): - with pytest.raises(ValueError): - def2.add_all_ingredients_in_output( - process_templates=[process1_link, process2_link], - project=project, - quantity_dimension=IngredientQuantityDimension.VOLUME - ) - - # If the process template has an empty allowed_names list then an error should be raised - session.set_responses( - ProcessTemplate( - process1_name, - uids={'id': process1_id}, - ).dump(), - ProcessTemplate( - process2_name, - uids={'id': process2_id}, - ).dump() - ) - with pytest.deprecated_call(): - with pytest.raises(RuntimeError): - empty_defn().add_all_ingredients_in_output( - process_templates=[process1_link, process2_link], - project=project, - quantity_dimension=IngredientQuantityDimension.VOLUME - ) - - def test_add_all_ingredients_in_output_via_team(session, team): """Test the behavior of TableConfig.add_all_ingredients_in_output.""" # GIVEN diff --git a/tests/serialization/test_design_spaces.py b/tests/serialization/test_design_spaces.py index 515a61c94..64f085a21 100644 --- a/tests/serialization/test_design_spaces.py +++ b/tests/serialization/test_design_spaces.py @@ -73,18 +73,6 @@ def test_enumerated_deserialization(valid_enumerated_design_space_data): assert design_space.data[1] == {'x': '2.0', 'color': 'green', 'formula': 'V2O3'} -def test_enumerated_serialization_data_int_deprecated(valid_enumerated_design_space_data): - design_space = EnumeratedDesignSpace.build(valid_enumerated_design_space_data) - with pytest.deprecated_call(): - design_space.data = [dict(x=1, color='red', formula='C44H54Si2')] - - -def test_enumerated_serialization_data_float_deprecated(valid_enumerated_design_space_data): - design_space = EnumeratedDesignSpace.build(valid_enumerated_design_space_data) - with pytest.deprecated_call(): - design_space.data = [dict(x=1.0, color='red', formula='C44H54Si2')] - - def test_enumerated_serialization(valid_enumerated_design_space_data): """Ensure that a serialized EnumeratedDesignSpace looks sane.""" design_space_serialization_check(valid_enumerated_design_space_data, EnumeratedDesignSpace) diff --git a/tests/serialization/test_predictors.py b/tests/serialization/test_predictors.py index be55fd1c9..bc456a445 100644 --- a/tests/serialization/test_predictors.py +++ b/tests/serialization/test_predictors.py @@ -19,8 +19,6 @@ def test_auto_ml_deserialization(valid_auto_ml_predictor_data): assert predictor.inputs[0] == RealDescriptor("x", lower_bound=0, upper_bound=100, units="") assert len(predictor.outputs) == 1 assert predictor.outputs[0] == RealDescriptor("z", lower_bound=0, upper_bound=100, units="") - with pytest.deprecated_call(): - assert len(predictor.training_data) == 0 def test_polymorphic_auto_ml_deserialization(valid_auto_ml_predictor_data): @@ -32,8 +30,6 @@ def test_polymorphic_auto_ml_deserialization(valid_auto_ml_predictor_data): assert predictor.inputs[0] == RealDescriptor("x", lower_bound=0, upper_bound=100, units="") assert len(predictor.outputs) == 1 assert predictor.outputs[0] == RealDescriptor("z", lower_bound=0, upper_bound=100, units="") - with pytest.deprecated_call(): - assert len(predictor.training_data) == 0 def test_legacy_serialization(valid_auto_ml_predictor_data):