[docs]classDocument(object):"""An Object or Document in a Descartes Labs service."""def__init__(self,saved=False,**kwargs)->None:self._attributes=dict()self._modified=set()ifsaved:self._load_from_remote(kwargs)else:self._fill(kwargs,remote=saved)self._saved=savedself._deleted=Falsedef__getattribute__(self,name:str)->Any:try:deleted=object.__getattribute__(self,"_deleted")exceptAttributeError:deleted=Falseifdeletedandname!="state"andnotname.startswith("_"):class_name=object.__getattribute__(self,"__class__").__name__raiseAttributeError(f"{class_name} has been deleted")returnobject.__getattribute__(self,name)def_clear_modified(self):"""Clears the list of modified attributes."""self._modified=set()def_get_attributes(self)->Dict[str,Attribute]:"""Returns all of the Attributes in the document. Returns ------- Dict[str, Attribute] The attribute instances in the document. """return{name:instanceforname,instanceinvars(self.__class__).items()ifisinstance(instance,Attribute)}def_fill(self,data:dict,ignore_missing:bool=False,remote:bool=False):"""Sets document attributes from a dictionary of data. Parameters ---------- ignore_missing : bool, False If set, unknown attributes will be ignored. remote : bool, False If set, the data is from the remote server. Data provided in this way will set immutable and readonly attributes. Additionally, the document will be forced into a `saved` status and all modified fields will be cleared. """attributes=self._get_attributes()forkey,valueindata.items():ifignore_missingandkeynotinattributes:continueattributes[key].__set__(self,value,force=remote)ifremote:self._clear_modified()self._saved=Truedef_load_from_remote(self,data:dict):"""Populates the document instance with data from the remote server. Parameters ---------- data : dict The response json to populate the document with. """self._fill(data,ignore_missing=True,remote=True)@classmethoddef_serialize_filter_attribute(cls,name:str,value:Any)->Tuple[str,Any]:"""Serializes a filter attribute. Parameters ---------- name : str The name of the attribute. value : Any The value of the attribute. Returns ------- Tuple[str, Any] The serialized attribute name and value. """attribute:Attribute=getattr(cls,name)return(attribute.name,attribute._serialize_to_filter(value))
[docs]defupdate(self,ignore_missing=False,**kwargs):"""Updates the document setting multiple attributes at a time. Parameters ---------- ignore_missing : bool, False If set, unknown attributes will be ignored. """self._fill(kwargs,ignore_missing=ignore_missing)
@propertydefstate(self)->DocumentState:"""Returns the state of the current document instance. Returns ------- :py:class:`~descarteslabs.common.client.DocumentState` """ifself._deleted:returnDocumentState.DELETEDifnotself._saved:returnDocumentState.NEWifself.is_modified:returnDocumentState.MODIFIEDelse:returnDocumentState.SAVED@propertydefis_modified(self)->bool:"""Determines if the document has been modified."""returnbool(self._modified)
[docs]defto_dict(self,only_modified:bool=False,exclude_readonly:bool=False,exclude_none:bool=False,)->Dict[str,Any]:"""Converts the document to a dictionary. Attributes will be serialized to JSON encodable types. Parameters ---------- only_modified : bool, False If set, only modified attributes and their values will be included. exclude_readonly : bool, False If set, readonly attributes and their values are excluded. exclude_none : bool, False If set, attributes with a value of None will be excluded. Returns ------- Dict[str, Any] The attributes matching the call parameters. The result of this function can be json encoded without modification. """attributes=self._get_attributes()data={}forkey,attributeinattributes.items():ifexclude_readonlyandattribute.readonly:continueifonly_modifiedandkeynotinself._modified:continuevalue=getattr(self,key)ifexclude_noneandvalueisNone:continueifisinstance(value,Document):value=value.to_dict(only_modified=only_modified,exclude_readonly=exclude_readonly,exclude_none=exclude_none,)else:value=attribute.serialize(value)data[key]=valuereturndata