Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

maint: 2025 R1 update #630

Merged
merged 3 commits into from
Oct 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions cicd/get_cleaned_db_entries.py
Original file line number Diff line number Diff line change
Expand Up @@ -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}'")
Expand Down Expand Up @@ -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,
Expand All @@ -121,7 +127,7 @@
)
)
layout_info.append(
models.GrantaServerApiSchemaLayoutsFullLayoutSection(
models.GsaFullLayoutSection(
name="Extra Attributes",
section_items=added_items,
display_names={},
Expand Down
4 changes: 2 additions & 2 deletions cicd/modify_custom_rs_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
26 changes: 14 additions & 12 deletions cicd/prepare_rs_db.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)


Expand Down Expand Up @@ -86,15 +86,15 @@ 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
)
return layout_response.guid

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
)
Expand All @@ -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,
Expand All @@ -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"],
Expand All @@ -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"]:
Expand All @@ -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

Expand All @@ -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

Expand Down
1 change: 1 addition & 0 deletions doc/changelog.d/630.documentation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
maint: 2025 R1 update
11 changes: 5 additions & 6 deletions examples/4_Sustainability/supporting-files/bom-2301-assembly.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
<Percentage>100.0</Percentage>
</Process>
<Process>
<MIProcessReference >
<MIProcessReference>
<dbKey xmlns="http://www.grantadesign.com/12/05/GrantaBaseTypes">MI_Restricted_Substances</dbKey>
<recordGUID xmlns="http://www.grantadesign.com/12/05/GrantaBaseTypes">907bda29-e800-44f6-b7ea-4eb8e7cff375</recordGUID>
</MIProcessReference>
Expand All @@ -41,7 +41,7 @@
<Quantity Unit="kg">0.0808</Quantity>
</Process>
<Process>
<MIProcessReference >
<MIProcessReference>
<dbKey xmlns="http://www.grantadesign.com/12/05/GrantaBaseTypes">MI_Restricted_Substances</dbKey>
<recordGUID xmlns="http://www.grantadesign.com/12/05/GrantaBaseTypes">03de1a28-7dd7-4354-bbd8-c839cfa00ec7</recordGUID>
</MIProcessReference>
Expand All @@ -58,7 +58,7 @@
<MassPerUom Unit="kg/Part">0.175</MassPerUom>
<PartNumber>Part1.1.B[LeafPart]</PartNumber>
<Materials>
<Material >
<Material>
<Percentage>100.0</Percentage>
<MIMaterialReference>
<dbKey xmlns="http://www.grantadesign.com/12/05/GrantaBaseTypes">MI_Restricted_Substances</dbKey>
Expand All @@ -76,7 +76,7 @@
<Percentage>100.0</Percentage>
</Process>
<Process>
<MIProcessReference >
<MIProcessReference>
<dbKey xmlns="http://www.grantadesign.com/12/05/GrantaBaseTypes">MI_Restricted_Substances</dbKey>
<recordGUID xmlns="http://www.grantadesign.com/12/05/GrantaBaseTypes">03de1a28-7dd7-4354-bbd8-c839cfa00ec7</recordGUID>
</MIProcessReference>
Expand Down Expand Up @@ -120,7 +120,7 @@
<dbKey xmlns="http://www.grantadesign.com/12/05/GrantaBaseTypes">MI_Restricted_Substances</dbKey>
<recordGUID xmlns="http://www.grantadesign.com/12/05/GrantaBaseTypes">92f90382-610a-4737-a18f-b153ea88e4ad</recordGUID>
</MIProcessReference>
<Identity>Primary processing, Metal extrusion, hot</Identity>
<Identity>Metal extrusion, hot</Identity>
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change isn't technically necessary. It was believed that the identity would override the name in the summary output, but the name in the database is always used instead.

<DimensionType>Mass</DimensionType>
<Percentage>100.0</Percentage>
</Process>
Expand Down Expand Up @@ -235,7 +235,6 @@
</Material>
</Materials>
</Part>

</Components>
</Part>
</Components>
Expand Down
27 changes: 14 additions & 13 deletions tests/test_integration_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand All @@ -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

Expand Down Expand Up @@ -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

Expand All @@ -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]
Expand All @@ -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
Expand All @@ -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
Expand Down
Loading