Source code for COMPS.Data.Suite

import json
from datetime import date, datetime
import logging
from enum import Enum
import uuid
import copy
from COMPS import Client
from COMPS.Data import Configuration, QueryCriteria, Experiment
from COMPS.Data.SerializableEntity import SerializableEntity, json_property, json_entity, parse_ISO8601_date, convert_if_string
from COMPS.Data.RelatableEntity import RelatableEntity
from COMPS.Data.TaggableEntity import TaggableEntity
from COMPS.Data.CommissionableEntity import CommissionableEntity

logger = logging.getLogger(__name__)

[docs]@json_entity() class Suite(TaggableEntity, CommissionableEntity, RelatableEntity, SerializableEntity): """ Represents a grouping of Experiments. Contains various basic properties accessible by getters (and, in some cases, +setters): * id * +name * +description * owner * date_created * last_modified Also contains "child objects" (which must be specifically requested for retrieval using the QueryCriteria.select_children() method of QueryCriteria): * tags * configuration """ def __init__(self, name, description=None, configuration=None): if not name: raise RuntimeError('Suite has not been initialized properly; non-null name required.') self._id = None self._name = name self._description = description self._owner = Client.auth_manager().username self._date_created = None self._last_modified = None self._tags = None self._configuration = configuration self._is_dirty = None # these will be set in _register_change() below self._is_config_dirty = None self._register_change(config_changed=(configuration is not None)) @classmethod def __internal_factory__(cls, id=None, name=None, description=None, owner=None, date_created=None, last_modified=None, tags=None, configuration=None): ste = cls.__new__(cls) ste._id = convert_if_string(id, uuid.UUID) ste._name = name ste._description = description ste._owner = owner ste._date_created = convert_if_string(date_created, parse_ISO8601_date) ste._last_modified = convert_if_string(last_modified, parse_ISO8601_date) ste._tags = tags if configuration: if isinstance(configuration, Configuration): ste._configuration = configuration else: config_json = Configuration.rest2py(configuration) ste._configuration = Configuration(**config_json) else: ste._configuration = None ste._is_dirty = False ste._is_config_dirty = False return ste @json_property() def id(self): return self._id @json_property() def name(self): return self._name @name.setter def name(self, name): self._name = name self._register_change() @json_property() def description(self): return self._description @description.setter def description(self, description): self._description = description self._register_change() @json_property() def owner(self): return self._owner @json_property() def date_created(self): return self._date_created @json_property() def last_modified(self): return self._last_modified @json_property() def tags(self): return self._tags # todo: immutable dict? @json_property() def configuration(self): return self._configuration @configuration.setter def configuration(self, configuration): self._configuration = configuration self._register_change(config_changed=True) ########################
[docs] @classmethod def get(cls, id=None, query_criteria=None): """ Retrieve one or more Suites. :param id: The id (str or UUID) of the Suite to retrieve :param query_criteria: A QueryCriteria object specifying basic property filters and tag-filters \ to apply to the set of Suites returned, as well as which properties and child-objects to \ fill for the returned Suites :return: A Suite or list of Suites (depending on whether 'id' was specified) with \ basic properties and child-objects assigned as specified by 'query_criteria' """ if id and not isinstance(id, uuid.UUID): try: id = uuid.UUID(id) except ValueError: raise ValueError('Invalid id: {0}'.format(id)) qc_params = query_criteria.to_param_dict(Suite) if query_criteria else {} path = '/Suites{0}'.format('/' + str(id) if id else '') resp = Client.get(path , params = qc_params) json_resp = resp.json() # if logger.isEnabledFor(logging.DEBUG): # logger.debug('Suite Response:') # logger.debug(json.dumps(json_resp, indent=4)) if 'Suites' not in json_resp or \ ( id is not None and len(json_resp['Suites']) != 1 ): logger.debug(json_resp) raise RuntimeError('Malformed Suites retrieve response!') stes = [] for ste_json in json_resp['Suites']: ste_json = cls.rest2py(ste_json) # if logger.isEnabledFor(logging.DEBUG): # logger.debug('Suite:') # logger.debug(json.dumps(ste_json, indent=4)) ste = Suite.__internal_factory__(**ste_json) stes.append(ste) if id is not None: return stes[0] else: return stes
[docs] def refresh(self, query_criteria=None): """ Update properties of an existing Suite from the server. :param query_criteria: A QueryCriteria object specifying which properties and child-objects \ to refresh on the Suite """ if not self._id: raise RuntimeError('Can\'t refresh a Suite that hasn\'t been saved!') ste = self.get(id=self.id, query_criteria=query_criteria) # if ste.id: self._id = ste.id if ste.name is not None: self._name = ste.name if ste.description is not None: self._description = ste.description if ste.owner is not None: self._owner = ste.owner if ste.date_created is not None: self._date_created = ste.date_created if ste.last_modified is not None: self._last_modified = ste.last_modified if ste.tags is not None: self._tags = ste.tags if ste.configuration is not None: self._configuration = ste.configuration
[docs] def get_experiments(self, query_criteria=None): """ Retrieve Experiments contained in this Suite. :param query_criteria: A QueryCriteria object specifying basic property filters and tag-filters \ to apply to the set of Experiments returned, as well as which properties and child-objects to \ fill for the returned Experiments :return: A list of Experiments with basic properties and child-objects assigned as specified \ by 'query_criteria' """ if not self._id: raise RuntimeError('Invalid call to get_experiments(); Suite hasn\'t been saved yet') qc = copy.copy(query_criteria) if query_criteria else QueryCriteria() qc = qc.where('suite_id={0}'.format(str(self._id))) return Experiment.get(query_criteria=qc)
[docs] def save(self): """ Save a single Suite. If it's a new Suite, an id is automatically assigned. """ if not self._is_dirty: logger.info('Suite has not been altered... no point in saving it!') return if not self._id: ste_to_save = self else: ste_to_save = self.__internal_factory__(id=self._id, name=self._name, description=self._description, configuration=self._configuration if self._is_config_dirty else None) save_ste = SerializableEntity.convertToDict(ste_to_save, include_hidden_props=True) # indentval = 4 if logger.isEnabledFor(logging.DEBUG) else None json_str = json.dumps({'Suites': [ save_ste ] }, # indent=indentval, default=lambda obj: obj.isoformat() + '0Z' if isinstance(obj, (date, datetime)) else str(obj) if isinstance(obj, uuid.UUID) else obj.name if isinstance(obj, Enum) else obj) resp = Client.post('/Suites' , data=json_str ) json_resp = resp.json() if not self._id: self._id = uuid.UUID(json_resp['Ids'][0]) self._is_dirty = False self._is_config_dirty = False
def _register_change(self, config_changed=False): if not self._is_dirty: self._is_dirty = True if config_changed and not self._is_config_dirty: self._is_config_dirty = True