Skip to content
Open
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
39 changes: 21 additions & 18 deletions compliance_tool/aas_compliance_tool/compliance_check_aasx.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (c) 2025 the Eclipse BaSyx Authors
# Copyright (c) 2026 the Eclipse BaSyx Authors
#
# This program and the accompanying materials are made available under the terms of the MIT License, available in
# the LICENSE file of this project.
Expand Down Expand Up @@ -31,7 +31,7 @@

def check_deserialization(file_path: str, state_manager: ComplianceToolStateManager,
file_info: Optional[str] = None) \
-> Tuple[model.DictObjectStore, aasx.DictSupplementaryFileContainer, pyecma376_2.OPCCoreProperties]:
-> Tuple[model.DictIdentifiableStore, aasx.DictSupplementaryFileContainer, pyecma376_2.OPCCoreProperties]:
"""
Read a AASX file and reports any issues using the given
:class:`~basyx.aas.compliance_tool.state_manager.ComplianceToolStateManager`
Expand Down Expand Up @@ -68,24 +68,24 @@ def check_deserialization(file_path: str, state_manager: ComplianceToolStateMana
state_manager.set_step_status_from_log()
state_manager.add_step('Read file')
state_manager.set_step_status(Status.NOT_EXECUTED)
return model.DictObjectStore(), aasx.DictSupplementaryFileContainer(), pyecma376_2.OPCCoreProperties()
return model.DictIdentifiableStore(), aasx.DictSupplementaryFileContainer(), pyecma376_2.OPCCoreProperties()

try:
# read given file
state_manager.add_step('Read file')
obj_store: model.DictObjectStore[model.Identifiable] = model.DictObjectStore()
identifiable_store: model.DictIdentifiableStore[model.Identifiable] = model.DictIdentifiableStore()
files = aasx.DictSupplementaryFileContainer()
reader.read_into(obj_store, files)
reader.read_into(identifiable_store, files)
new_cp = reader.get_core_properties()
state_manager.set_step_status(Status.SUCCESS)
except (ValueError, KeyError) as error:
logger.error(error)
state_manager.set_step_status(Status.FAILED)
return model.DictObjectStore(), aasx.DictSupplementaryFileContainer(), pyecma376_2.OPCCoreProperties()
return model.DictIdentifiableStore(), aasx.DictSupplementaryFileContainer(), pyecma376_2.OPCCoreProperties()
finally:
reader.close()

return obj_store, files, new_cp
return identifiable_store, files, new_cp


def check_schema(file_path: str, state_manager: ComplianceToolStateManager) -> None:
Expand Down Expand Up @@ -174,7 +174,7 @@ def check_aas_example(file_path: str, state_manager: ComplianceToolStateManager,
logger_example.propagate = False
logger_example.setLevel(logging.INFO)

obj_store, files, cp_new = check_deserialization(file_path, state_manager)
identifiable_store, files, cp_new = check_deserialization(file_path, state_manager)

if state_manager.status in (Status.FAILED, Status.NOT_EXECUTED):
state_manager.add_step('Check if data is equal to example data')
Expand All @@ -187,7 +187,7 @@ def check_aas_example(file_path: str, state_manager: ComplianceToolStateManager,

state_manager.add_step('Check if data is equal to example data')
example_data = create_example_aas_binding()
checker.check_object_store(obj_store, example_data)
checker.check_identifiable_store(identifiable_store, example_data)
state_manager.add_log_records_from_data_checker(checker)

if state_manager.status in (Status.FAILED, Status.NOT_EXECUTED):
Expand Down Expand Up @@ -238,22 +238,25 @@ def check_aas_example(file_path: str, state_manager: ComplianceToolStateManager,

# Check if file in file object is the same
list_of_id_shorts = ["ExampleSubmodelCollection", "ExampleFile"]
obj = example_data.get_identifiable("https://acplt.org/Test_Submodel")
identifiable = example_data.get_item("https://acplt.org/Test_Submodel")
for id_short in list_of_id_shorts:
obj = obj.get_referable(id_short)
obj2 = obj_store.get_identifiable("https://acplt.org/Test_Submodel")
identifiable = identifiable.get_referable(id_short)
obj2 = identifiable_store.get_item("https://acplt.org/Test_Submodel")
for id_short in list_of_id_shorts:
obj2 = obj2.get_referable(id_short)
try:
sha_file = files.get_sha256(obj.value)
sha_file = files.get_sha256(identifiable.value)
except KeyError as error:
state_manager.add_log_records_from_data_checker(checker2)
logger.error(error)
state_manager.set_step_status(Status.FAILED)
return

checker2.check(sha_file == files.get_sha256(obj2.value), "File of {} must be {}.".format(obj.value, obj2.value),
value=obj2.value)
checker2.check(
sha_file == files.get_sha256(obj2.value),
"File of {} must be {}.".format(identifiable.value, obj2.value),
value=obj2.value
)
state_manager.add_log_records_from_data_checker(checker2)
if state_manager.status in (Status.FAILED, Status.NOT_EXECUTED):
state_manager.set_step_status(Status.FAILED)
Expand All @@ -280,9 +283,9 @@ def check_aasx_files_equivalence(file_path_1: str, file_path_2: str, state_manag
logger.propagate = False
logger.setLevel(logging.INFO)

obj_store_1, files_1, cp_1 = check_deserialization(file_path_1, state_manager, 'first')
identifiable_store_1, files_1, cp_1 = check_deserialization(file_path_1, state_manager, 'first')

obj_store_2, files_2, cp_2 = check_deserialization(file_path_2, state_manager, 'second')
identifiable_store_2, files_2, cp_2 = check_deserialization(file_path_2, state_manager, 'second')

if state_manager.status is Status.FAILED:
state_manager.add_step('Check if data in files are equal')
Expand All @@ -294,7 +297,7 @@ def check_aasx_files_equivalence(file_path_1: str, file_path_2: str, state_manag
checker = AASDataChecker(raise_immediately=False, **kwargs)
try:
state_manager.add_step('Check if data in files are equal')
checker.check_object_store(obj_store_1, obj_store_2)
checker.check_identifiable_store(identifiable_store_1, identifiable_store_2)
except (KeyError, AssertionError) as error:
state_manager.set_step_status(Status.FAILED)
logger.error(error)
Expand Down
22 changes: 11 additions & 11 deletions compliance_tool/aas_compliance_tool/compliance_check_json.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (c) 2025 the Eclipse BaSyx Authors
# Copyright (c) 2026 the Eclipse BaSyx Authors
#
# This program and the accompanying materials are made available under the terms of the MIT License, available in
# the LICENSE file of this project.
Expand Down Expand Up @@ -102,7 +102,7 @@ def _check_schema(file_to_be_checked: IO[str], state_manager: ComplianceToolStat


def check_deserialization(file_path: str, state_manager: ComplianceToolStateManager,
file_info: Optional[str] = None) -> model.DictObjectStore:
file_info: Optional[str] = None) -> model.DictIdentifiableStore:
"""
Deserializes a JSON AAS file and reports any issues using the given
:class:`~basyx.aas.compliance_tool.state_manager.ComplianceToolStateManager`
Expand All @@ -112,7 +112,7 @@ def check_deserialization(file_path: str, state_manager: ComplianceToolStateMana
:param file_path: Given file which should be deserialized
:param state_manager: :class:`~basyx.aas.compliance_tool.state_manager.ComplianceToolStateManager` to log the steps
:param file_info: Additional information about the file for name of the steps
:return: The deserialized :class:`~basyx.aas.model.provider.DictObjectStore`
:return: The deserialized :class:`~basyx.aas.model.provider.DictIdentifiableStore`
"""
logger = logging.getLogger('compliance_check')
logger.addHandler(state_manager)
Expand Down Expand Up @@ -140,7 +140,7 @@ def check_deserialization(file_path: str, state_manager: ComplianceToolStateMana
else:
state_manager.add_step('Read file and check if it is deserializable')
state_manager.set_step_status(Status.NOT_EXECUTED)
return model.DictObjectStore()
return model.DictIdentifiableStore()

with file_to_be_checked:
state_manager.set_step_status(Status.SUCCESS)
Expand All @@ -149,11 +149,11 @@ def check_deserialization(file_path: str, state_manager: ComplianceToolStateMana
state_manager.add_step('Read file {} and check if it is deserializable'.format(file_info))
else:
state_manager.add_step('Read file and check if it is deserializable')
obj_store = json_deserialization.read_aas_json_file(file_to_be_checked, failsafe=True)
identifiable_store = json_deserialization.read_aas_json_file(file_to_be_checked, failsafe=True)

state_manager.set_step_status_from_log()

return obj_store
return identifiable_store


def check_aas_example(file_path: str, state_manager: ComplianceToolStateManager, **kwargs) -> None:
Expand All @@ -174,7 +174,7 @@ def check_aas_example(file_path: str, state_manager: ComplianceToolStateManager,
logger_example.propagate = False
logger_example.setLevel(logging.INFO)

obj_store = check_deserialization(file_path, state_manager)
identifiable_store = check_deserialization(file_path, state_manager)

if state_manager.status in (Status.FAILED, Status.NOT_EXECUTED):
state_manager.add_step('Check if data is equal to example data')
Expand All @@ -184,7 +184,7 @@ def check_aas_example(file_path: str, state_manager: ComplianceToolStateManager,
checker = AASDataChecker(raise_immediately=False, **kwargs)

state_manager.add_step('Check if data is equal to example data')
checker.check_object_store(obj_store, create_example())
checker.check_identifiable_store(identifiable_store, create_example())

state_manager.add_log_records_from_data_checker(checker)

Expand All @@ -208,9 +208,9 @@ def check_json_files_equivalence(file_path_1: str, file_path_2: str, state_manag
logger.propagate = False
logger.setLevel(logging.INFO)

obj_store_1 = check_deserialization(file_path_1, state_manager, 'first')
identifiable_store_1 = check_deserialization(file_path_1, state_manager, 'first')

obj_store_2 = check_deserialization(file_path_2, state_manager, 'second')
identifiable_store_2 = check_deserialization(file_path_2, state_manager, 'second')

if state_manager.status is Status.FAILED:
state_manager.add_step('Check if data in files are equal')
Expand All @@ -220,7 +220,7 @@ def check_json_files_equivalence(file_path_1: str, file_path_2: str, state_manag
checker = AASDataChecker(raise_immediately=False, **kwargs)
try:
state_manager.add_step('Check if data in files are equal')
checker.check_object_store(obj_store_1, obj_store_2)
checker.check_identifiable_store(identifiable_store_1, identifiable_store_2)
except (KeyError, AssertionError) as error:
state_manager.set_step_status(Status.FAILED)
logger.error(error)
Expand Down
18 changes: 9 additions & 9 deletions compliance_tool/aas_compliance_tool/compliance_check_xml.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ def _check_schema(file_to_be_checked, state_manager):


def check_deserialization(file_path: str, state_manager: ComplianceToolStateManager,
file_info: Optional[str] = None) -> model.DictObjectStore:
file_info: Optional[str] = None) -> model.DictIdentifiableStore:
"""
Deserializes a XML AAS file and reports any issues using the given
:class:`~basyx.aas.compliance_tool.state_manager.ComplianceToolStateManager`
Expand Down Expand Up @@ -139,7 +139,7 @@ def check_deserialization(file_path: str, state_manager: ComplianceToolStateMana
else:
state_manager.add_step('Read file and check if it is deserializable')
state_manager.set_step_status(Status.NOT_EXECUTED)
return model.DictObjectStore()
return model.DictIdentifiableStore()

with file_to_be_checked:
state_manager.set_step_status(Status.SUCCESS)
Expand All @@ -148,11 +148,11 @@ def check_deserialization(file_path: str, state_manager: ComplianceToolStateMana
state_manager.add_step('Read file {} and check if it is deserializable'.format(file_info))
else:
state_manager.add_step('Read file and check if it is deserializable')
obj_store = xml_deserialization.read_aas_xml_file(file_to_be_checked, failsafe=True)
identifiable_store = xml_deserialization.read_aas_xml_file(file_to_be_checked, failsafe=True)

state_manager.set_step_status_from_log()

return obj_store
return identifiable_store


def check_aas_example(file_path: str, state_manager: ComplianceToolStateManager, **kwargs) -> None:
Expand All @@ -173,7 +173,7 @@ def check_aas_example(file_path: str, state_manager: ComplianceToolStateManager,
logger_example.propagate = False
logger_example.setLevel(logging.INFO)

obj_store = check_deserialization(file_path, state_manager)
identifiable_store = check_deserialization(file_path, state_manager)

if state_manager.status in (Status.FAILED, Status.NOT_EXECUTED):
state_manager.add_step('Check if data is equal to example data')
Expand All @@ -183,7 +183,7 @@ def check_aas_example(file_path: str, state_manager: ComplianceToolStateManager,
checker = AASDataChecker(raise_immediately=False, **kwargs)

state_manager.add_step('Check if data is equal to example data')
checker.check_object_store(obj_store, create_example())
checker.check_identifiable_store(identifiable_store, create_example())

state_manager.add_log_records_from_data_checker(checker)

Expand All @@ -207,9 +207,9 @@ def check_xml_files_equivalence(file_path_1: str, file_path_2: str, state_manage
logger.propagate = False
logger.setLevel(logging.INFO)

obj_store_1 = check_deserialization(file_path_1, state_manager, 'first')
identifiable_store_1 = check_deserialization(file_path_1, state_manager, 'first')

obj_store_2 = check_deserialization(file_path_2, state_manager, 'second')
identifiable_store_2 = check_deserialization(file_path_2, state_manager, 'second')

if state_manager.status is Status.FAILED:
state_manager.add_step('Check if data in files are equal')
Expand All @@ -219,7 +219,7 @@ def check_xml_files_equivalence(file_path_1: str, file_path_2: str, state_manage
checker = AASDataChecker(raise_immediately=False, **kwargs)
try:
state_manager.add_step('Check if data in files are equal')
checker.check_object_store(obj_store_1, obj_store_2)
checker.check_identifiable_store(identifiable_store_1, identifiable_store_2)
except (KeyError, AssertionError) as error:
state_manager.set_step_status(Status.FAILED)
logger.error(error)
Expand Down
2 changes: 1 addition & 1 deletion compliance_tool/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ requires-python = ">=3.10"
dependencies = [
"pyecma376-2>=0.2.4",
"jsonschema>=4.21.1",
"basyx-python-sdk>=1.0.0",
"basyx-python-sdk @ file:../sdk",
]

[project.optional-dependencies]
Expand Down
12 changes: 6 additions & 6 deletions compliance_tool/test/test_aas_compliance_tool.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (c) 2025 the Eclipse BaSyx Authors
# Copyright (c) 2026 the Eclipse BaSyx Authors
#
# This program and the accompanying materials are made available under the terms of the MIT License, available in
# the LICENSE file of this project.
Expand Down Expand Up @@ -138,10 +138,10 @@ def test_json_create_example(self) -> None:
self.assertIn('SUCCESS: Write data to file', str(output.stdout))

with open(filename, "r", encoding='utf-8-sig') as f:
json_object_store = read_aas_json_file(f, failsafe=False)
json_identifiable_store = read_aas_json_file(f, failsafe=False)
data = create_example()
checker = AASDataChecker(raise_immediately=True)
checker.check_object_store(json_object_store, data)
checker.check_identifiable_store(json_identifiable_store, data)
os.unlink(filename)

def test_json_deserialization(self) -> None:
Expand Down Expand Up @@ -184,10 +184,10 @@ def test_xml_create_example(self) -> None:
self.assertIn('SUCCESS: Write data to file', str(output.stdout))

with open(filename, "rb") as f:
xml_object_store = read_aas_xml_file(f, failsafe=False)
xml_identifiable_store = read_aas_xml_file(f, failsafe=False)
data = create_example()
checker = AASDataChecker(raise_immediately=True)
checker.check_object_store(xml_object_store, data)
checker.check_identifiable_store(xml_identifiable_store, data)
os.unlink(filename)

def test_xml_deseralization(self) -> None:
Expand Down Expand Up @@ -229,7 +229,7 @@ def test_aasx_create_example(self) -> None:
self.assertIn('SUCCESS: Write data to file', str(output.stdout))

# Read AASX file
new_data: model.DictObjectStore[model.Identifiable] = model.DictObjectStore()
new_data: model.DictIdentifiableStore[model.Identifiable] = model.DictIdentifiableStore()
new_files = aasx.DictSupplementaryFileContainer()
with aasx.AASXReader(filename) as reader:
reader.read_into(new_data, new_files)
Expand Down
4 changes: 3 additions & 1 deletion etc/scripts/check_python_versions_supported.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ def main(min_version: str, max_version: str) -> None:
response = requests.get("https://endoflife.date/api/python.json")
response.raise_for_status()
eol_data = response.json()
eol_versions = {entry["cycle"]: {"eol": entry["eol"], "releaseDate": entry["releaseDate"]} for entry in eol_data}
eol_versions = {
entry["cycle"]: {"eol": entry["eol"], "releaseDate": entry["releaseDate"]} for entry in eol_data
}

# Get current date to compare with EoL and release dates
current_date = datetime.now().date()
Expand Down
6 changes: 3 additions & 3 deletions sdk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ Serialize the `Submodel` to XML:
```python
from basyx.aas.adapter.xml import write_aas_xml_file

data: model.DictObjectStore[model.Identifiable] = model.DictObjectStore()
data: model.DictIdentifiableStore[model.Identifiable] = model.DictIdentifiableStore()
data.add(submodel)
write_aas_xml_file(file='Simple_Submodel.xml', data=data)
```
Expand All @@ -124,10 +124,10 @@ write_aas_xml_file(file='Simple_Submodel.xml', data=data)
For further examples and tutorials, check out the `basyx.aas.examples`-package. Here is a quick overview:

* [`tutorial_create_simple_aas`](./basyx/aas/examples/tutorial_create_simple_aas.py): Create an Asset Administration Shell, including an Asset object and a Submodel
* [`tutorial_storage`](./basyx/aas/examples/tutorial_storage.py): Manage a larger number of Asset Administration Shells in an ObjectStore and resolve references
* [`tutorial_storage`](./basyx/aas/examples/tutorial_storage.py): Manage a larger number of Asset Administration Shells in an IdentifiableStore and resolve references
* [`tutorial_serialization_deserialization`](./basyx/aas/examples/tutorial_serialization_deserialization.py): Use the JSON and XML serialization/deserialization for single objects or full standard-compliant files
* [`tutorial_aasx`](./basyx/aas/examples/tutorial_aasx.py): Export Asset Administration Shells with related objects and auxiliary files to AASX package files
* [`tutorial_backend_couchdb`](./basyx/aas/examples/tutorial_backend_couchdb.py): Use the *CouchDBObjectStore* to manage and retrieve AAS objects in a CouchDB document database
* [`tutorial_backend_couchdb`](./basyx/aas/examples/tutorial_backend_couchdb.py): Use the *CouchDBIdentifiableStore* to manage and retrieve AAS objects in a CouchDB document database


### Documentation
Expand Down
Loading