diff --git a/cicd/get_cleaned_db_entries.py b/cicd/get_cleaned_db_entries.py index 3f1904b8..84cc924e 100644 --- a/cicd/get_cleaned_db_entries.py +++ b/cicd/get_cleaned_db_entries.py @@ -74,11 +74,17 @@ # Generally static unless the BoM Analytics Servers logic has changed, or these attributes have been added to the layout # Both of these scenarios are unlikely # dict[Table name: list[Attribute name]] -extra_attributes = {"Coatings": ["Coating Code"], "Legislations and Lists": ["Legislation ID", "Short title"]} +extra_attributes = { + "Coatings": ["Coating Code"], + "Legislations and Lists": ["Legislation ID", "Short title"], +} # Will generally be different for each release, and may be empty. -# dict[Table name: dict[Current attribute name: New attribute name]] -renamed_attributes = {"Products and parts": {"General comments": "Comments"}} +renamed_attributes = { + # "Table name": { + # "Old attribute name": "New attribute name", + # } +} info = {} logger.info(f"Reading records and attributes from database '{DB_KEY}'") @@ -109,7 +115,7 @@ for extra_attribute_name in relevant_attribute_names: attribute_info = attribute_name_map[extra_attribute_name] added_items.append( - models.GrantaServerApiSchemaLayoutsLayoutAttributeItem( + models.GsaLayoutAttributeItem( attribute_type=attribute_info.type, underlying_entity_guid=attribute_info.guid, name=attribute_info.name, @@ -121,7 +127,7 @@ ) ) layout_info.append( - models.GrantaServerApiSchemaLayoutsFullLayoutSection( + models.GsaFullLayoutSection( name="Extra Attributes", section_items=added_items, display_names={}, diff --git a/cicd/modify_custom_rs_db.py b/cicd/modify_custom_rs_db.py index 6c735b19..c39fa042 100644 --- a/cicd/modify_custom_rs_db.py +++ b/cicd/modify_custom_rs_db.py @@ -60,10 +60,10 @@ database_client = api.SchemaDatabasesApi(api_client) logger.info("Renaming Database") - database_info: models.GrantaServerApiSchemaDatabase = database_client.get_database(database_key=CUSTOM_DB_KEY) + database_info: models.GsaDatabase = database_client.get_database(database_key=CUSTOM_DB_KEY) guid = database_info.guid new_name = "Restricted Substances Custom Tables" - rename_request = models.GrantaServerApiSchemaUpdateDatabase(name=new_name) + rename_request = models.GsaUpdateDatabase(name=new_name) database_client.update_database(database_key=CUSTOM_DB_KEY, body=rename_request) diff --git a/cicd/prepare_rs_db.py b/cicd/prepare_rs_db.py index 4996bc33..3fea992e 100644 --- a/cicd/prepare_rs_db.py +++ b/cicd/prepare_rs_db.py @@ -57,7 +57,7 @@ def get_table_name_guid_map(self, db_key: str) -> Mapping[str, str]: def update_table_name(self, db_key: str, table_guid: str, new_table_name: str) -> None: tables_api = api.SchemaTablesApi(self._client) self.logger.info(f"Updating Table - {db_key}:{table_guid} with name '{new_table_name}'") - patch_request = models.GrantaServerApiSchemaTablesUpdateTable(name=new_table_name) + patch_request = models.GsaUpdateTable(name=new_table_name) tables_api.update_table(database_key=db_key, table_guid=table_guid, body=patch_request) @@ -86,7 +86,7 @@ def delete_layout(self, layout_guid: str) -> None: def create_layout(self, layout_name: str) -> str: logger.info(f"Creating new layout '{layout_name}'") - layout_request = models.GrantaServerApiSchemaLayoutsCreateLayout(name=layout_name) + layout_request = models.GsaCreateLayout(name=layout_name) layout_response = self._layouts_api.create_layout( database_key=self._db_key, table_guid=self._table_guid, body=layout_request ) @@ -94,7 +94,7 @@ def create_layout(self, layout_name: str) -> str: def create_layout_section(self, layout_guid: str, section_name: str) -> str: logger.info(f"Creating new layout section '{section_name}' in layout '{layout_guid}'") - section_request = models.GrantaServerApiSchemaLayoutsCreateLayoutSection(name=section_name) + section_request = models.GsaCreateLayoutSection(name=section_name) section_response = self._layout_sections_api.create_section( # noqa: E501 database_key=self._db_key, table_guid=self._table_guid, layout_guid=layout_guid, body=section_request ) @@ -105,6 +105,8 @@ def add_layout_section_item(self, layout_guid: str, layout_section_guid: str, it f"Adding new item '{item_information['name']}' to layout section '{layout_section_guid}' in layout '{layout_guid}'" # noqa: E501 ) new_section_item = self._process_layout_item(item_information) + if new_section_item is None: + return self._layout_sections_api.create_layout_item( # noqa: E501 database_key=self._db_key, table_guid=self._table_guid, @@ -113,25 +115,25 @@ def add_layout_section_item(self, layout_guid: str, layout_section_guid: str, it body=new_section_item, ) - def _process_layout_item(self, item_information: Mapping) -> models.GrantaServerApiSchemaLayoutsNewLayoutItem: + def _process_layout_item(self, item_information: Mapping) -> models.GsaNewLayoutItem | None: if item_information["item_type"] == "attribute": return self._process_attribute(item_information) elif item_information["item_type"] == "link": if item_information["link_type"] == "associationChain": return self._process_association_chain(item_information) + elif item_information["link_type"] == "crossDatabaseLink": + return None raise NotImplementedError("Other layout items are not supported yet...") def _process_association_chain(self, layout_item): item_name = layout_item["name"] logger.info(f"--Association Chain - '{item_name}'") links = self._process_association_chain_link(layout_item) - return models.GrantaServerApiSchemaLayoutsNewLayoutAssociationChainItem( - association_chain_name=item_name, association_chain_links=links - ) + return models.GsaNewLayoutAssociationChainItem(association_chain_name=item_name, association_chain_links=links) def _process_association_chain_link(self, chain_link): links = [ - models.GrantaServerApiSchemaLayoutsNewLayoutAssociationChainLink( + models.GsaNewLayoutAssociationChainLink( forwards=chain_link["forwards"], tabular_attribute_guid=chain_link["underlying_entity_guid"], source_database_version_guid=chain_link["target_database"], @@ -148,12 +150,12 @@ def _process_attribute(self, layout_item: Mapping): meta_names = [i["name"] for i in layout_item["meta_attributes"]] attribute_guid = self._attribute_name_map[attribute_name] - new_section_item = models.GrantaServerApiSchemaLayoutsNewLayoutAttributeItem(attribute_guid=attribute_guid) + new_section_item = models.GsaNewLayoutAttributeItem(attribute_guid=attribute_guid) if layout_item["tabular_columns"] is not None: detailed_attribute_info = self._attributes_api.get_attribute( database_key=self._db_key, table_guid=self._table_guid, attribute_guid=attribute_guid ) - assert isinstance(detailed_attribute_info, models.GrantaServerApiSchemaAttributesTabularAttribute) + assert isinstance(detailed_attribute_info, models.GsaTabularAttribute) column_map = {column.name: column for column in detailed_attribute_info.tabular_columns} columns = [] for column_item in layout_item["tabular_columns"]: @@ -169,7 +171,7 @@ def _process_attribute(self, layout_item: Mapping): for meta_name in meta_names: logger.info(f"----{meta_name}") meta_item = meta_map[meta_name] - metas.append(models.GrantaServerApiSchemaLayoutsNewLayoutAttributeItem(attribute_guid=meta_item)) + metas.append(models.GsaNewLayoutAttributeItem(attribute_guid=meta_item)) new_section_item.meta_attributes = metas return new_section_item @@ -190,7 +192,7 @@ def delete_subset(self, db_key: str, table_guid: str, subset_guid: str): def create_subset(self, db_key: str, table_guid: str, subset_name: str) -> str: subsets_api = api.SchemaSubsetsApi(self._client) self.logger.info(f"Creating new subset '{subset_name}'") - subset_request = models.GrantaServerApiSchemaSubsetsCreateSubset(name=subset_name) + subset_request = models.GsaCreateSubset(name=subset_name) subset_response = subsets_api.create_subset(database_key=db_key, table_guid=table_guid, body=subset_request) return subset_response.guid diff --git a/doc/changelog.d/630.documentation.md b/doc/changelog.d/630.documentation.md new file mode 100644 index 00000000..d2e27fcb --- /dev/null +++ b/doc/changelog.d/630.documentation.md @@ -0,0 +1 @@ +maint: 2025 R1 update \ No newline at end of file diff --git a/examples/4_Sustainability/supporting-files/bom-2301-assembly.xml b/examples/4_Sustainability/supporting-files/bom-2301-assembly.xml index a991dfc1..248b240e 100644 --- a/examples/4_Sustainability/supporting-files/bom-2301-assembly.xml +++ b/examples/4_Sustainability/supporting-files/bom-2301-assembly.xml @@ -32,7 +32,7 @@ 100.0 - + MI_Restricted_Substances 907bda29-e800-44f6-b7ea-4eb8e7cff375 @@ -41,7 +41,7 @@ 0.0808 - + MI_Restricted_Substances 03de1a28-7dd7-4354-bbd8-c839cfa00ec7 @@ -58,7 +58,7 @@ 0.175 Part1.1.B[LeafPart] - + 100.0 MI_Restricted_Substances @@ -76,7 +76,7 @@ 100.0 - + MI_Restricted_Substances 03de1a28-7dd7-4354-bbd8-c839cfa00ec7 @@ -120,7 +120,7 @@ MI_Restricted_Substances 92f90382-610a-4737-a18f-b153ea88e4ad - Primary processing, Metal extrusion, hot + Metal extrusion, hot Mass 100.0 @@ -235,7 +235,6 @@ - diff --git a/tests/test_integration_tests.py b/tests/test_integration_tests.py index 34de4d52..abf3e199 100644 --- a/tests/test_integration_tests.py +++ b/tests/test_integration_tests.py @@ -297,15 +297,16 @@ def test_sustainability_summary_query(self, connection): assert beryllium_summary.mass_before_processing.value == pytest.approx(0.027) assert beryllium_summary.material_reference.record_guid is not None assert beryllium_summary.climate_change.value == pytest.approx(15.52, DEFAULT_TOLERANCE) - assert beryllium_summary.climate_change_percentage == pytest.approx(49.25, DEFAULT_TOLERANCE) + assert beryllium_summary.climate_change_percentage == pytest.approx(48.52, DEFAULT_TOLERANCE) assert beryllium_summary.embodied_energy.value == pytest.approx(117.55, DEFAULT_TOLERANCE) - assert beryllium_summary.embodied_energy_percentage == pytest.approx(36.34, DEFAULT_TOLERANCE) + assert beryllium_summary.embodied_energy_percentage == pytest.approx(35.28, DEFAULT_TOLERANCE) # Check expected summaries for primary processes - assert len(response.primary_processes_details) == 3 + assert len(response.primary_processes_details) == 4 expected_primary_processes = [ ("Primary processing, Casting", "stainless-astm-cn-7ms-cast"), ("Primary processing, Casting", "steel-1010-annealed"), + ("Primary processing, Metal extrusion, hot", "steel-1010-annealed"), ("Other", None), ] primary_processes = [(p.process_name, p.material_identity) for p in response.primary_processes_details] @@ -314,10 +315,10 @@ def test_sustainability_summary_query(self, connection): # Spot check primary process primary_process = response.primary_processes_details[1] - assert primary_process.climate_change.value == pytest.approx(14.75, DEFAULT_TOLERANCE) - assert primary_process.embodied_energy.value == pytest.approx(210.68, DEFAULT_TOLERANCE) - assert primary_process.climate_change_percentage == pytest.approx(39.40, DEFAULT_TOLERANCE) - assert primary_process.embodied_energy_percentage == pytest.approx(39.22, DEFAULT_TOLERANCE) + assert primary_process.climate_change.value == pytest.approx(3.98, DEFAULT_TOLERANCE) + assert primary_process.embodied_energy.value == pytest.approx(54.99, DEFAULT_TOLERANCE) + assert primary_process.climate_change_percentage == pytest.approx(34.96, DEFAULT_TOLERANCE) + assert primary_process.embodied_energy_percentage == pytest.approx(34.35, DEFAULT_TOLERANCE) assert primary_process.material_reference.record_guid is not None assert primary_process.process_reference.record_guid is not None @@ -389,8 +390,8 @@ def test_sustainability_query(self, connection): assert product.input_part_number == "Part1[ProductAssembly]" assert product._reference_value is None assert product.reported_mass.value == pytest.approx(4.114, DEFAULT_TOLERANCE) - assert product.climate_change.value == pytest.approx(75.04, DEFAULT_TOLERANCE) - assert product.embodied_energy.value == pytest.approx(951.61, DEFAULT_TOLERANCE) + assert product.climate_change.value == pytest.approx(49.33, DEFAULT_TOLERANCE) + assert product.embodied_energy.value == pytest.approx(578.29, DEFAULT_TOLERANCE) assert len(product.parts) == 5 @@ -403,8 +404,8 @@ def test_sustainability_query(self, connection): assert subassembly.input_part_number == "Part1.1[SubAssembly]" assert subassembly._reference_value is None assert subassembly.reported_mass.value == pytest.approx(1.45, DEFAULT_TOLERANCE) - assert subassembly.climate_change.value == pytest.approx(32.864, DEFAULT_TOLERANCE) - assert subassembly.embodied_energy.value == pytest.approx(453.53, DEFAULT_TOLERANCE) + assert subassembly.climate_change.value == pytest.approx(17.93, DEFAULT_TOLERANCE) + assert subassembly.embodied_energy.value == pytest.approx(235.97, DEFAULT_TOLERANCE) # JF process jf_process = subassembly.processes[0] @@ -422,7 +423,7 @@ def test_sustainability_query(self, connection): assert leaf_part.input_part_number == "Part1.A[LeafPart]" assert leaf_part._reference_value is None assert leaf_part.climate_change.value == pytest.approx(1.75, DEFAULT_TOLERANCE) - assert leaf_part.embodied_energy.value == pytest.approx(24.99, DEFAULT_TOLERANCE) + assert leaf_part.embodied_energy.value == pytest.approx(25.37, DEFAULT_TOLERANCE) assert leaf_part.reported_mass.value == pytest.approx(0.61, DEFAULT_TOLERANCE) # Leaf part -> Material @@ -432,7 +433,7 @@ def test_sustainability_query(self, connection): assert material.record_guid is not None assert material.climate_change.value == pytest.approx(1.06, DEFAULT_TOLERANCE) - assert material.embodied_energy.value == pytest.approx(14.30, DEFAULT_TOLERANCE) + assert material.embodied_energy.value == pytest.approx(14.68, DEFAULT_TOLERANCE) assert material.reported_mass.value == pytest.approx(0.61, DEFAULT_TOLERANCE) assert material.recyclable is True assert material.functional_recycle is True