Loading openflexure_microscope/api/v2/views/captures.py +19 −10 Original line number Diff line number Diff line Loading @@ -17,9 +17,9 @@ class InstrumentSchema(Schema): state = fields.Dict() class CaptureMetadataImageSchema(Schema): class ImageSchema(Schema): id = fields.UUID() acquisitionDate = fields.String(format="date") time = fields.String(format="date") format = fields.String() name = fields.String() tags = fields.List(fields.String()) Loading @@ -30,19 +30,20 @@ class CaptureMetadataSchema(Schema): experimenter = fields.Dict() # TODO: Make schema experimenterGroup = fields.Dict() # TODO: Make schema dataset = fields.Dict() # TODO: Make schema image = fields.Nested(CaptureMetadataImageSchema()) image = fields.Nested(ImageSchema()) instrument = fields.Nested(InstrumentSchema()) class CaptureSchema(Schema): id = fields.String() class CaptureSchema(ImageSchema): """ Schema containing only basic attributes required for interacting with a capture. Additional attributes are returned by using FullCaptureSchema """ dataset = fields.Dict() # TODO: Make schema file = fields.String( data_key="path", description="Path of file on microscope device" ) exists = fields.Bool(data_key="available") name = fields.String() metadata = fields.Nested(CaptureMetadataSchema()) links = fields.Dict() @pre_dump Loading Loading @@ -91,6 +92,14 @@ class CaptureSchema(Schema): return data class FullCaptureSchema(CaptureSchema): """ Capture schema including metadata. We exclude this by default since it can become huge due to complex settings including lens shading tables and CSM matrices. """ metadata = fields.Nested(CaptureMetadataSchema()) class CaptureList(PropertyView): tags = ["captures"] Loading @@ -108,7 +117,7 @@ class CaptureList(PropertyView): class CaptureView(View): tags = ["captures"] @marshal_with(CaptureSchema()) @marshal_with(FullCaptureSchema()) def get(self, id_): """ Description of a single image capture Loading openflexure_microscope/captures/capture.py +38 −5 Original line number Diff line number Diff line Loading @@ -120,7 +120,8 @@ class CaptureObject(object): # Store a nice ID self.id = uuid.uuid4() #: str: Unique capture ID logging.debug("Created CaptureObject {}".format(self.id)) self.datetime = datetime.datetime.now() self.time = datetime.datetime.now() # Create file name. Default to UUID self.format = None Loading @@ -130,12 +131,15 @@ class CaptureObject(object): if not os.path.exists(self.filefolder): os.makedirs(self.filefolder) # Dictionary for adding top-level metadata (cannmot be accessed through web API) # Dictionary for adding top-level metadata # This can ONLY be modified by the server application # Top level metadata cannot be modified via the web API self._metadata = {} # Dictionary for storing custom annotations # Can be modified via the web API self.annotations = {} # List for storing tags # Can be modified via the web API self.tags = [] def write(self, s): Loading Loading @@ -173,6 +177,22 @@ class CaptureObject(object): else: return False @property def dataset(self) -> str: """ If capture is part of a dataset, return basic dataset info. Otherwise return None """ dataset = self.metadata.get("dataset") if not dataset: return None return { "id": dataset.get("id"), "name": dataset.get("name"), "type": dataset.get("type") } # HANDLE TAGS def put_tags(self, tags: list): """ Loading @@ -199,7 +219,7 @@ class CaptureObject(object): self.save_metadata() # HANDLE METADATA # HANDLE ANNOTATIONS def put_annotations(self, data: dict) -> None: """ Loading @@ -211,6 +231,13 @@ class CaptureObject(object): self.annotations.update(data) self.save_metadata() def delete_annotation(self, key: str) -> None: if key in self.annotations: del self.annotations[key] self.save_metadata() # HANDLE METADATA def put_metadata(self, data: dict) -> None: """ Merge root metadata from a passed dictionary into the capture metadata, and saves. Loading @@ -230,6 +257,8 @@ class CaptureObject(object): """ self._metadata = data # BULK OPERATIONS def put_and_save( self, tags: list = None, annotations: dict = None, metadata: dict = None ): Loading Loading @@ -273,6 +302,8 @@ class CaptureObject(object): piexif.insert(exif_bytes, self.file) logging.info("Finished saving metadata to %s", self.file) # PROPERTIES @property def metadata(self) -> dict: """ Loading @@ -283,7 +314,7 @@ class CaptureObject(object): "image": { "id": self.id, "name": self.name, "acquisitionDate": self.datetime.isoformat(), "time": self.time.isoformat(), "format": self.format, "tags": self.tags, "annotations": self.annotations, Loading Loading @@ -354,6 +385,8 @@ class CaptureObject(object): piexif.insert(exif_bytes, self.file) return io.BytesIO(thumbnail) # FILE MANAGEMENT def save(self) -> None: """Write stream to file, and save/update metadata file""" # If a stream OR file exists, save the metadata file Loading Loading
openflexure_microscope/api/v2/views/captures.py +19 −10 Original line number Diff line number Diff line Loading @@ -17,9 +17,9 @@ class InstrumentSchema(Schema): state = fields.Dict() class CaptureMetadataImageSchema(Schema): class ImageSchema(Schema): id = fields.UUID() acquisitionDate = fields.String(format="date") time = fields.String(format="date") format = fields.String() name = fields.String() tags = fields.List(fields.String()) Loading @@ -30,19 +30,20 @@ class CaptureMetadataSchema(Schema): experimenter = fields.Dict() # TODO: Make schema experimenterGroup = fields.Dict() # TODO: Make schema dataset = fields.Dict() # TODO: Make schema image = fields.Nested(CaptureMetadataImageSchema()) image = fields.Nested(ImageSchema()) instrument = fields.Nested(InstrumentSchema()) class CaptureSchema(Schema): id = fields.String() class CaptureSchema(ImageSchema): """ Schema containing only basic attributes required for interacting with a capture. Additional attributes are returned by using FullCaptureSchema """ dataset = fields.Dict() # TODO: Make schema file = fields.String( data_key="path", description="Path of file on microscope device" ) exists = fields.Bool(data_key="available") name = fields.String() metadata = fields.Nested(CaptureMetadataSchema()) links = fields.Dict() @pre_dump Loading Loading @@ -91,6 +92,14 @@ class CaptureSchema(Schema): return data class FullCaptureSchema(CaptureSchema): """ Capture schema including metadata. We exclude this by default since it can become huge due to complex settings including lens shading tables and CSM matrices. """ metadata = fields.Nested(CaptureMetadataSchema()) class CaptureList(PropertyView): tags = ["captures"] Loading @@ -108,7 +117,7 @@ class CaptureList(PropertyView): class CaptureView(View): tags = ["captures"] @marshal_with(CaptureSchema()) @marshal_with(FullCaptureSchema()) def get(self, id_): """ Description of a single image capture Loading
openflexure_microscope/captures/capture.py +38 −5 Original line number Diff line number Diff line Loading @@ -120,7 +120,8 @@ class CaptureObject(object): # Store a nice ID self.id = uuid.uuid4() #: str: Unique capture ID logging.debug("Created CaptureObject {}".format(self.id)) self.datetime = datetime.datetime.now() self.time = datetime.datetime.now() # Create file name. Default to UUID self.format = None Loading @@ -130,12 +131,15 @@ class CaptureObject(object): if not os.path.exists(self.filefolder): os.makedirs(self.filefolder) # Dictionary for adding top-level metadata (cannmot be accessed through web API) # Dictionary for adding top-level metadata # This can ONLY be modified by the server application # Top level metadata cannot be modified via the web API self._metadata = {} # Dictionary for storing custom annotations # Can be modified via the web API self.annotations = {} # List for storing tags # Can be modified via the web API self.tags = [] def write(self, s): Loading Loading @@ -173,6 +177,22 @@ class CaptureObject(object): else: return False @property def dataset(self) -> str: """ If capture is part of a dataset, return basic dataset info. Otherwise return None """ dataset = self.metadata.get("dataset") if not dataset: return None return { "id": dataset.get("id"), "name": dataset.get("name"), "type": dataset.get("type") } # HANDLE TAGS def put_tags(self, tags: list): """ Loading @@ -199,7 +219,7 @@ class CaptureObject(object): self.save_metadata() # HANDLE METADATA # HANDLE ANNOTATIONS def put_annotations(self, data: dict) -> None: """ Loading @@ -211,6 +231,13 @@ class CaptureObject(object): self.annotations.update(data) self.save_metadata() def delete_annotation(self, key: str) -> None: if key in self.annotations: del self.annotations[key] self.save_metadata() # HANDLE METADATA def put_metadata(self, data: dict) -> None: """ Merge root metadata from a passed dictionary into the capture metadata, and saves. Loading @@ -230,6 +257,8 @@ class CaptureObject(object): """ self._metadata = data # BULK OPERATIONS def put_and_save( self, tags: list = None, annotations: dict = None, metadata: dict = None ): Loading Loading @@ -273,6 +302,8 @@ class CaptureObject(object): piexif.insert(exif_bytes, self.file) logging.info("Finished saving metadata to %s", self.file) # PROPERTIES @property def metadata(self) -> dict: """ Loading @@ -283,7 +314,7 @@ class CaptureObject(object): "image": { "id": self.id, "name": self.name, "acquisitionDate": self.datetime.isoformat(), "time": self.time.isoformat(), "format": self.format, "tags": self.tags, "annotations": self.annotations, Loading Loading @@ -354,6 +385,8 @@ class CaptureObject(object): piexif.insert(exif_bytes, self.file) return io.BytesIO(thumbnail) # FILE MANAGEMENT def save(self) -> None: """Write stream to file, and save/update metadata file""" # If a stream OR file exists, save the metadata file Loading