def send( base: Base, transports: List[AbstractTransport] = [], use_default_cache: bool = True, ): """Sends an object via the provided transports. Defaults to the local cache. Arguments: obj {Base} -- the object you want to send transports {list} -- where you want to send them use_default_cache {bool} -- toggle for the default cache. If set to false, it will only send to the provided transports Returns: str -- the object id of the sent object """ metrics.track(metrics.SEND) if not transports and not use_default_cache: raise SpeckleException( message="You need to provide at least one transport: cannot send with an empty transport list and no default cache" ) if use_default_cache: transports.insert(0, SQLiteTransport()) serializer = BaseObjectSerializer(write_transports=transports) for t in transports: t.begin_write() hash, _ = serializer.write_json(base=base) for t in transports: t.end_write() return hash
def test_object_create(self, client, stream, base): transport = MemoryTransport() s = BaseObjectSerializer(write_transports=[transport], read_transport=transport) _, base_dict = s.traverse_base(base) obj_id = client.object.create(stream_id=stream.id, objects=[base_dict])[0] assert isinstance(obj_id, str) assert obj_id == base.get_id(True)
def test_object_create(self, client, stream, base): transport = SQLiteTransport() s = BaseObjectSerializer(write_transports=[transport], read_transport=transport) _, base_dict = s.traverse_base(base) obj_id = client.object.create(stream_id=stream.id, objects=[base_dict])[0] assert isinstance(obj_id, str) assert base_dict["@detach"]["speckle_type"] == "reference" assert obj_id == base.get_id(True)
def serialize(base: Base, write_transports: List[AbstractTransport] = []) -> str: """ Serialize a base object. If no write transports are provided, the object will be serialized without detaching or chunking any of the attributes. Arguments: base {Base} -- the object to serialize write_transports {List[AbstractTransport]} -- optional: the transports to write to Returns: str -- the serialized object """ metrics.track(metrics.SERIALIZE) serializer = BaseObjectSerializer(write_transports=write_transports) return serializer.write_json(base)[1]
def _parse_response(self, response: dict or list, schema=None): """Try to create a class instance from the response""" if isinstance(response, list): return [ self._parse_response(response=r, schema=schema) for r in response ] if schema: return schema.parse_obj(response) elif self.schema: try: return self.schema.parse_obj(response) except: s = BaseObjectSerializer(read_transport=SQLiteTransport()) return s.recompose_base(response) else: return response
def deserialize( obj_string: str, read_transport: AbstractTransport = SQLiteTransport() ) -> Base: """ Deserialize a string object into a Base object. If the object contains referenced child objects that are not stored in the local db, a read transport needs to be provided in order to recompose the base with the children objects. Arguments: obj_string {str} -- the string object to deserialize read_transport {AbstractTransport} -- the transport to fetch children objects from (defaults to SQLiteTransport) Returns: Base -- the deserialized object """ serializer = BaseObjectSerializer(read_transport=read_transport) return serializer.read_json(obj_string=obj_string)
def get_id(self, decompose: bool = False) -> str: """ Gets the id (a unique hash) of this object. ⚠️ This method fully serializes the object which, in the case of large objects (with many sub-objects), has a tangible cost. Avoid using it! Note: the hash of a decomposed object differs from that of a non-decomposed object Arguments: decompose {bool} -- if True, will decompose the object in the process of hashing it Returns: str -- the hash (id) of the fully serialized object """ from specklepy.serialization.base_object_serializer import BaseObjectSerializer serializer = BaseObjectSerializer() if decompose: serializer.write_transports = [MemoryTransport()] return serializer.traverse_base(self)[0]
def receive( obj_id: str, remote_transport: AbstractTransport = None, local_transport: AbstractTransport = None, ) -> Base: """Receives an object from a transport. Arguments: obj_id {str} -- the id of the object to receive remote_transport {Transport} -- the transport to receive from local_transport {Transport} -- the local cache to check for existing objects (defaults to `SQLiteTransport`) Returns: Base -- the base object """ metrics.track(metrics.RECEIVE) if not local_transport: local_transport = SQLiteTransport() serializer = BaseObjectSerializer(read_transport=local_transport) # try local transport first. if the parent is there, we assume all the children are there and continue wth deserialisation using the local transport obj_string = local_transport.get_object(obj_id) if obj_string: return serializer.read_json(obj_string=obj_string) if not remote_transport: raise SpeckleException( message="Could not find the specified object using the local transport, and you didn't provide a fallback remote from which to pull it." ) obj_string = remote_transport.copy_object_and_children( id=obj_id, target_transport=local_transport ) return serializer.read_json(obj_string=obj_string)