From cd8101e821942341a03f6800a200df96f617e74d Mon Sep 17 00:00:00 2001 From: Stuart McHattie Date: Thu, 15 Feb 2024 16:41:06 +0000 Subject: [PATCH 1/2] Simplify location creation code Remove the padding method and turn the location creation into a list comprehension --- .../definitions/labware_type.py | 39 +++++-------------- 1 file changed, 9 insertions(+), 30 deletions(-) diff --git a/tol_lab_share/message_properties/definitions/labware_type.py b/tol_lab_share/message_properties/definitions/labware_type.py index 1e3dc00f..0d71c006 100644 --- a/tol_lab_share/message_properties/definitions/labware_type.py +++ b/tol_lab_share/message_properties/definitions/labware_type.py @@ -1,3 +1,4 @@ +import string from .message_property import MessageProperty from tol_lab_share import error_codes import logging @@ -31,39 +32,17 @@ def check_labware_type(self): self.trigger_error(error_codes.ERROR_6_LABWARE_TYPE, text=f"input: {self._input.value}") return result - def pad_number(self, number: int) -> str: - """Given a number, it generates a string of size 2 padded with zeros at the left representing - the same value. Eg: 3 would be converted to '03', while 12 would be converted to '12'. - Parameters: - number (int) value we want to convert - Returns: - str with the padded value - """ - padded_number = str(number) - if len(padded_number) == 1: - padded_number = f"0{padded_number}" - return padded_number - - def _locations_for_plate12x8_column_order(self) -> list[str]: - """It generates the list of all valid locations for a labware type following column - order. Eg: ['A01', 'B01', 'C01', .... 'H12'] - Returns: - list[str] with al the valid locations - """ - locations = [] - for number in range(12): - for letter_ord in range(ord("A"), ord("H") + 1): - locations.append(f"{chr(letter_ord)}{self.pad_number(number+1)}") - return locations - def valid_locations(self) -> list[str]: - """It returns the list of valid locations for the labware type. If the labware type is - a tube, it returns ane empty list. If it is a plate 12x8 it returns all locations in - column order. + """It returns the list of valid locations for the labware type. + If the labware type is a tube, it returns ane empty list. + If it is a plate 12x8 it returns all locations in column order. i.e. ['A01', 'B01', 'C01', .... 'H12'] + Returns: - list[str] with all the valid locations + list[str]: A list with all the valid locations. """ if self.value == "Plate12x8": - return self._locations_for_plate12x8_column_order() + return [ + f"{letter}{str(number).zfill(2)}" for number in range(1, 13) for letter in string.ascii_uppercase[:8] + ] else: return [] From d6c81b1f32e07f9bc2b47b583bbe60314efa1cea Mon Sep 17 00:00:00 2001 From: Stuart McHattie Date: Thu, 15 Feb 2024 16:47:46 +0000 Subject: [PATCH 2/2] Use datetime.utcnow() in tests Not strictly necessary, but it's better practice than the locale affected now() method --- tests/conftest.py | 8 +++---- .../data/examples_create_labware_messages.py | 20 +++++++++--------- .../definitions/test_message_property.py | 2 +- .../messages/test_output_traction_message.py | 10 ++++----- tests/messages/test_traction_qc_message.py | 21 ++++++------------- tools/demo/testing_data.py | 14 ++++++------- 6 files changed, 33 insertions(+), 42 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 34f82b79..ec02422b 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -138,7 +138,7 @@ def valid_sample(): "countryOfOrigin": "United Kingdom", "genomeSize": "14", "accessionNumber": "EE1234", - "sampleCollectionDateUtc": datetime.now(), + "sampleCollectionDateUtc": datetime.utcnow(), "costCode": "S1234", "shearedFemtoFragmentSize": "8", "postSPRIConcentration": "9", @@ -147,7 +147,7 @@ def valid_sample(): "finalNanoDrop230": "200", "finalNanoDrop": "150", "shearingAndQCComments": "", - "dateSubmittedUTC": datetime.now(), + "dateSubmittedUTC": datetime.utcnow(), "priorityLevel": "Medium", } @@ -171,7 +171,7 @@ def invalid_sample(): "genomeSize": "14", "accessionNumber": "EE1234", "costCode": 1234, - "sampleCollectionDateUtc": datetime.now(), + "sampleCollectionDateUtc": datetime.utcnow(), "shearedFemtoFragmentSize": "8", "postSPRIConcentration": "9", "postSPRIVolume": "10", @@ -179,7 +179,7 @@ def invalid_sample(): "finalNanoDrop230": 200, "finalNanoDrop": "150", "shearingAndQCComments": "", - "dateSubmittedUTC": datetime.now(), + "dateSubmittedUTC": datetime.utcnow(), "priorityLevel": "Medium", } diff --git a/tests/data/examples_create_labware_messages.py b/tests/data/examples_create_labware_messages.py index 2ec57687..6592ee21 100644 --- a/tests/data/examples_create_labware_messages.py +++ b/tests/data/examples_create_labware_messages.py @@ -3,7 +3,7 @@ TEST_CREATE_LABWARE_MSG_OBJECT: dict[str, Any] = { "messageUuid": "b01aa0ad-7b19-4f94-87e9-70d74fb8783c".encode(), - "messageCreateDateUtc": datetime.now(), + "messageCreateDateUtc": datetime.utcnow(), "labware": { "labwareType": "Plate12x8", "barcode": "BARCODE001", @@ -24,7 +24,7 @@ "countryOfOrigin": "United Kingdom", "genomeSize": "14", "accessionNumber": "EE3383", - "sampleCollectionDateUtc": datetime.now(), + "sampleCollectionDateUtc": datetime.utcnow(), "costCode": "S1234", "shearedFemtoFragmentSize": "5", "postSPRIConcentration": "10", @@ -33,7 +33,7 @@ "finalNanoDrop230": "6", "finalNanoDrop": "7", "shearingAndQCComments": "Comments", - "dateSubmittedUTC": datetime.now(), + "dateSubmittedUTC": datetime.utcnow(), "priorityLevel": "Medium", }, { @@ -52,7 +52,7 @@ "countryOfOrigin": "United Kingdom", "genomeSize": "14", "accessionNumber": "EE3383", - "sampleCollectionDateUtc": datetime.now(), + "sampleCollectionDateUtc": datetime.utcnow(), "costCode": "S1234", "shearedFemtoFragmentSize": "5", "postSPRIConcentration": "10", @@ -61,7 +61,7 @@ "finalNanoDrop230": "6", "finalNanoDrop": "7", "shearingAndQCComments": "Comments", - "dateSubmittedUTC": datetime.now(), + "dateSubmittedUTC": datetime.utcnow(), "priorityLevel": "Medium", }, ], @@ -71,7 +71,7 @@ TEST_INVALID_CREATE_LABWARE_MSG_OBJECT: dict[str, Any] = { "messageUuid": "b01aa0ad7b19-4f94-87e9-70d74fb8783c".encode(), - "messageCreateDateUtc": datetime.now(), + "messageCreateDateUtc": datetime.utcnow(), "labware": { "labwareType": "Plate12x8", "barcode": "BARCODE001", @@ -92,7 +92,7 @@ "countryOfOrigin": "United Kingdom", "genomeSize": "14", "accessionNumber": "EE3383", - "sampleCollectionDateUtc": datetime.now(), + "sampleCollectionDateUtc": datetime.utcnow(), "costCode": "S1234", "shearedFemtoFragmentSize": "5", "postSPRIConcentration": "10", @@ -101,7 +101,7 @@ "finalNanoDrop230": "6", "finalNanoDrop": 7, "shearingAndQCComments": "Comments", - "dateSubmittedUTC": datetime.now(), + "dateSubmittedUTC": datetime.utcnow(), "priorityLevel": "Medium", }, { @@ -120,7 +120,7 @@ "countryOfOrigin": "United Kingdom", "genomeSize": "14", "accessionNumber": "EE3383", - "sampleCollectionDateUtc": datetime.now(), + "sampleCollectionDateUtc": datetime.utcnow(), "costCode": "S1234", "shearedFemtoFragmentSize": "5", "postSPRIConcentration": "10", @@ -129,7 +129,7 @@ "finalNanoDrop230": "6", "finalNanoDrop": "7", "shearingAndQCComments": "Comments", - "dateSubmittedUTC": datetime.now(), + "dateSubmittedUTC": datetime.utcnow(), "priorityLevel": "Medium", }, ], diff --git a/tests/message_properties/definitions/test_message_property.py b/tests/message_properties/definitions/test_message_property.py index b77ffe25..d009f192 100644 --- a/tests/message_properties/definitions/test_message_property.py +++ b/tests/message_properties/definitions/test_message_property.py @@ -134,7 +134,7 @@ def test_message_property_check_is_date_utc(): instance = MessageProperty(Input(None)) assert instance.check_is_date_utc() is False - instance = MessageProperty(Input(datetime.now())) + instance = MessageProperty(Input(datetime.utcnow())) assert instance.check_is_date_utc() is True instance = MessageProperty(Input({})) diff --git a/tests/messages/test_output_traction_message.py b/tests/messages/test_output_traction_message.py index 4380fa42..b6aeb57c 100644 --- a/tests/messages/test_output_traction_message.py +++ b/tests/messages/test_output_traction_message.py @@ -37,7 +37,7 @@ def test_output_traction_message_can_validate(): def test_output_traction_message_can_generate_payload_for_plates(): - my_date = datetime.now() + my_date = datetime.utcnow() instance = OutputTractionMessage() request = instance.create_request() @@ -144,7 +144,7 @@ def test_output_traction_message_can_generate_payload_for_plates(): def test_output_traction_message_can_generate_payload_for_multiple_plates(): - my_date = datetime.now() + my_date = datetime.utcnow() instance = OutputTractionMessage() # Mix the order of the requests to ensure the grouping for plates works. @@ -348,7 +348,7 @@ def test_output_traction_message_can_generate_payload_for_multiple_plates(): def test_output_traction_message_can_generate_payload_for_ont_library_types(): - my_date = datetime.now() + my_date = datetime.utcnow() instance = OutputTractionMessage() request = instance.create_request() @@ -457,7 +457,7 @@ def test_output_traction_message_can_generate_payload_for_ont_library_types(): def test_output_traction_message_can_generate_payload_for_tubes(): - my_date = datetime.now() + my_date = datetime.utcnow() instance = OutputTractionMessage() request = instance.create_request() @@ -558,7 +558,7 @@ def test_output_traction_message_can_generate_payload_for_tubes(): def test_output_traction_message_can_generate_payload_for_mix_of_plate_and_tubes(): - my_date = datetime.now() + my_date = datetime.utcnow() instance = OutputTractionMessage() request = instance.create_request() diff --git a/tests/messages/test_traction_qc_message.py b/tests/messages/test_traction_qc_message.py index 678e2533..3d4499ff 100644 --- a/tests/messages/test_traction_qc_message.py +++ b/tests/messages/test_traction_qc_message.py @@ -9,18 +9,9 @@ logger = logging.getLogger(__name__) -class FreezeDate(datetime): - @classmethod - def now(cls): - return cls(2023, 7, 11, 12, 29, 11, 564246) - - -datetime = FreezeDate # type: ignore - - class TestTractionQcMessage: @pytest.fixture() - def valid_traction_qc_message(self): + def valid_traction_qc_message(self, freezer): traction_qc_message = TractionQcMessage() request = traction_qc_message.create_request() @@ -33,7 +24,7 @@ def valid_traction_qc_message(self): request.final_nano_drop_230 = "230" request.final_nano_drop = "200" request.shearing_qc_comments = "Comments" - request.date_submitted_utc = datetime.now().timestamp() * 1000 + request.date_submitted_utc = datetime.utcnow().timestamp() * 1000 request = traction_qc_message.create_request() request.sanger_sample_id = "sanger_sample_id_DDD2" @@ -45,7 +36,7 @@ def valid_traction_qc_message(self): request.final_nano_drop_230 = "130" request.final_nano_drop = "100" request.shearing_qc_comments = "" - request.date_submitted_utc = datetime.now().timestamp() * 1000 + request.date_submitted_utc = datetime.utcnow().timestamp() * 1000 return traction_qc_message @@ -66,7 +57,7 @@ def test_validate_traction_qc_message(self, valid_traction_qc_message, invalid_t assert not invalid_traction_qc_message.validate() assert valid_traction_qc_message.validate() - def test_can_generate_correct_payload(self, valid_traction_qc_message): + def test_can_generate_correct_payload(self, valid_traction_qc_message, freezer): payload = valid_traction_qc_message.payload() expected_payload = { @@ -81,7 +72,7 @@ def test_can_generate_correct_payload(self, valid_traction_qc_message): "post_spri_volume": "20", "sheared_femto_fragment_size": "5", "shearing_qc_comments": "Comments", - "date_submitted": datetime.now().timestamp() * 1000, + "date_submitted": datetime.utcnow().timestamp() * 1000, "labware_barcode": "FD20706500", "sample_external_id": "sanger_sample_id_DDD", }, @@ -92,7 +83,7 @@ def test_can_generate_correct_payload(self, valid_traction_qc_message): "post_spri_concentration": "10", "post_spri_volume": "30", "sheared_femto_fragment_size": "9", - "date_submitted": datetime.now().timestamp() * 1000, + "date_submitted": datetime.utcnow().timestamp() * 1000, "labware_barcode": "FD20706501", "sample_external_id": "sanger_sample_id_DDD2", }, diff --git a/tools/demo/testing_data.py b/tools/demo/testing_data.py index 2e91a4f7..0fa05d90 100644 --- a/tools/demo/testing_data.py +++ b/tools/demo/testing_data.py @@ -20,7 +20,7 @@ def build_create_labware_96_msg(unique_id, num_msg): unique_id_lab = f"TOLTESTING-PLATE-{unique_id}-{num_msg}" return { "messageUuid": str(uuid4()).encode(), - "messageCreateDateUtc": datetime.now().timestamp() * 1000, + "messageCreateDateUtc": datetime.utcnow().timestamp() * 1000, "labware": { "labwareType": "Plate12x8", "barcode": barcode_for_unique_id("PLATE", unique_id, num_msg), @@ -42,7 +42,7 @@ def build_create_labware_96_msg(unique_id, num_msg): "genomeSize": "1", "accessionNumber": "A1234", "costCode": "S1234", - "sampleCollectionDateUtc": datetime.now().timestamp() * 1000, + "sampleCollectionDateUtc": datetime.utcnow().timestamp() * 1000, "shearedFemtoFragmentSize": "5", "postSPRIConcentration": "10", "postSPRIVolume": "20", @@ -50,7 +50,7 @@ def build_create_labware_96_msg(unique_id, num_msg): "finalNanoDrop230": "6", "finalNanoDrop": "7", "shearingAndQCComments": "Comments", - "dateSubmittedUTC": datetime.now().timestamp() * 1000, + "dateSubmittedUTC": datetime.utcnow().timestamp() * 1000, "priorityLevel": "Medium", } for letter in range(ord("A"), ord("H") + 1) @@ -64,7 +64,7 @@ def build_create_tube_msg(unique_id, num_msg): unique_id_lab = f"TOLTESTING-TUBE-{unique_id}-{num_msg}" return { "messageUuid": str(uuid4()).encode(), - "messageCreateDateUtc": datetime.now().timestamp() * 1000, + "messageCreateDateUtc": datetime.utcnow().timestamp() * 1000, "labware": { "labwareType": "Tube", "barcode": barcode_for_unique_id("TUBE", unique_id, num_msg), @@ -86,7 +86,7 @@ def build_create_tube_msg(unique_id, num_msg): "genomeSize": "1", "accessionNumber": "A1234", "costCode": "S1234", - "sampleCollectionDateUtc": datetime.now().timestamp() * 1000, + "sampleCollectionDateUtc": datetime.utcnow().timestamp() * 1000, "shearedFemtoFragmentSize": "5", "postSPRIConcentration": "10", "postSPRIVolume": "20", @@ -94,7 +94,7 @@ def build_create_tube_msg(unique_id, num_msg): "finalNanoDrop230": "6", "finalNanoDrop": "7", "shearingAndQCComments": "Comments", - "dateSubmittedUTC": datetime.now().timestamp() * 1000, + "dateSubmittedUTC": datetime.utcnow().timestamp() * 1000, "priorityLevel": "Medium", } ], @@ -105,7 +105,7 @@ def build_create_tube_msg(unique_id, num_msg): def build_update_labware_msg(sample_msg): return { "messageUuid": str(uuid4()).encode(), - "messageCreateDateUtc": datetime.now().timestamp() * 1000, + "messageCreateDateUtc": datetime.utcnow().timestamp() * 1000, "sampleUpdates": [ { "sampleUuid": sample_msg["labware"]["samples"][3]["sampleUuid"],