Skip to content

Commit 81994f1

Browse files
committed
Merge develop
2 parents 01767c1 + 10ff4e4 commit 81994f1

68 files changed

Lines changed: 2109 additions & 860 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 30 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name: ci
33
on: [push, pull_request]
44

55
env:
6-
X_PYTHON_MIN_VERSION: "3.9"
6+
X_PYTHON_MIN_VERSION: "3.10"
77
X_PYTHON_MAX_VERSION: "3.12"
88

99
jobs:
@@ -22,7 +22,7 @@ jobs:
2222
- name: Install Python dependencies
2323
run: |
2424
python -m pip install --upgrade pip
25-
pip install -r ./check_python_versions_requirements.txt
25+
python -m pip install -r ./check_python_versions_requirements.txt
2626
- name: Check Supported Python Versions
2727
run: |
2828
python check_python_versions_supported.py \
@@ -45,7 +45,7 @@ jobs:
4545
runs-on: ubuntu-latest
4646
strategy:
4747
matrix:
48-
python-version: ["3.9", "3.12"]
48+
python-version: ["3.10", "3.12"]
4949
env:
5050
COUCHDB_ADMIN_PASSWORD: "yo0Quai3"
5151
# (2024-10-11, s-heppner)
@@ -85,17 +85,17 @@ jobs:
8585
- name: Install Python dependencies
8686
run: |
8787
python -m pip install --upgrade pip
88-
pip install .[dev]
88+
python -m pip install .[dev]
8989
- name: Setup test config and CouchDB database server
9090
run: |
9191
python test/_helper/setup_testdb.py -u "admin" -p "$COUCHDB_ADMIN_PASSWORD"
9292
- name: Test with coverage + unittest
9393
run: |
94-
coverage run --source=basyx -m unittest
94+
python -m coverage run --source=basyx -m unittest
9595
- name: Report test coverage
9696
if: ${{ always() }}
9797
run: |
98-
coverage report -m
98+
python -m coverage report -m
9999
100100
sdk-static-analysis:
101101
# This job runs static code analysis, namely pycodestyle and mypy
@@ -112,13 +112,13 @@ jobs:
112112
- name: Install Python dependencies
113113
run: |
114114
python -m pip install --upgrade pip
115-
pip install .[dev]
115+
python -m pip install .[dev]
116116
- name: Check typing with MyPy
117117
run: |
118-
mypy basyx test
118+
python -m mypy basyx test
119119
- name: Check code style with PyCodestyle
120120
run: |
121-
pycodestyle --count --max-line-length 120 basyx test
121+
python -m pycodestyle --count --max-line-length 120 basyx test
122122
123123
sdk-readme-codeblocks:
124124
# This job runs the same static code analysis (mypy and pycodestyle) on the codeblocks in our docstrings.
@@ -135,16 +135,17 @@ jobs:
135135
- name: Install Python dependencies
136136
run: |
137137
python -m pip install --upgrade pip
138-
pip install .[dev]
138+
python -m pip install .[dev]
139139
- name: Check typing with MyPy
140+
shell: bash
140141
run: |
141-
mypy <(codeblocks python README.md)
142+
python -m mypy <(python -m codeblocks python README.md)
142143
- name: Check code style with PyCodestyle
143144
run: |
144-
codeblocks --wrap python README.md | pycodestyle --count --max-line-length 120 -
145+
python -m codeblocks --wrap python README.md | python -m pycodestyle --count --max-line-length 120 -
145146
- name: Run readme codeblocks with Python
146147
run: |
147-
codeblocks python README.md | python
148+
python -m codeblocks python README.md | python
148149
149150
sdk-docs:
150151
# This job checks, if the automatically generated documentation using sphinx can be compiled
@@ -161,7 +162,7 @@ jobs:
161162
- name: Install Python dependencies
162163
run: |
163164
python -m pip install --upgrade pip
164-
pip install .[docs]
165+
python -m pip install .[docs]
165166
- name: Check documentation for errors
166167
run: |
167168
SPHINXOPTS="-a -E -n -W --keep-going" make -C docs html
@@ -181,7 +182,7 @@ jobs:
181182
- name: Install dependencies
182183
run: |
183184
python -m pip install --upgrade pip
184-
pip install build
185+
python -m pip install build
185186
- name: Create source and wheel dist
186187
run: |
187188
python -m build
@@ -208,7 +209,7 @@ jobs:
208209
runs-on: ubuntu-latest
209210
strategy:
210211
matrix:
211-
python-version: ["3.9", "3.12"]
212+
python-version: ["3.10", "3.12"]
212213
defaults:
213214
run:
214215
working-directory: ./compliance_tool
@@ -223,15 +224,15 @@ jobs:
223224
# install the local sdk in editable mode so it does not get overwritten
224225
run: |
225226
python -m pip install --upgrade pip
226-
pip install -e ../sdk[dev]
227-
pip install .[dev]
227+
python -m pip install ../sdk
228+
python -m pip install .[dev]
228229
- name: Test with coverage + unittest
229230
run: |
230-
coverage run --source=aas_compliance_tool -m unittest
231+
python -m coverage run --source=aas_compliance_tool -m unittest
231232
- name: Report test coverage
232233
if: ${{ always() }}
233234
run: |
234-
coverage report -m
235+
python -m coverage report -m
235236
236237
compliance-tool-static-analysis:
237238
# This job runs static code analysis, namely pycodestyle and mypy
@@ -250,14 +251,14 @@ jobs:
250251
# install the local sdk in editable mode so it does not get overwritten
251252
run: |
252253
python -m pip install --upgrade pip
253-
pip install -e ../sdk[dev]
254-
pip install .[dev]
254+
python -m pip install ../sdk
255+
python -m pip install .[dev]
255256
- name: Check typing with MyPy
256257
run: |
257-
mypy aas_compliance_tool test
258+
python -m mypy aas_compliance_tool test
258259
- name: Check code style with PyCodestyle
259260
run: |
260-
pycodestyle --count --max-line-length 120 aas_compliance_tool test
261+
python -m pycodestyle --count --max-line-length 120 aas_compliance_tool test
261262
262263
compliance-tool-package:
263264
# This job checks if we can build our compliance_tool package
@@ -275,7 +276,7 @@ jobs:
275276
- name: Install dependencies
276277
run: |
277278
python -m pip install --upgrade pip
278-
pip install build
279+
python -m pip install build
279280
- name: Create source and wheel dist
280281
run: |
281282
python -m build
@@ -301,14 +302,14 @@ jobs:
301302
- name: Install Python dependencies
302303
run: |
303304
python -m pip install --upgrade pip
304-
pip install ../../sdk
305-
pip install .[dev]
305+
python -m pip install ../../sdk
306+
python -m pip install .[dev]
306307
- name: Check typing with MyPy
307308
run: |
308-
mypy .
309+
python -m mypy .
309310
- name: Check code style with PyCodestyle
310311
run: |
311-
pycodestyle --count --max-line-length 120 .
312+
python -m pycodestyle --count --max-line-length 120 .
312313
313314
server-package:
314315
# This job checks if we can build our server package

.gitignore

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ htmlcov/
2121
docs/build/
2222
.hypothesis/
2323

24-
# customized config files
24+
# Customized config files
2525
sdk/test/test_config.ini
2626
# Schema files needed for testing
2727
sdk/test/adapter/schemas
@@ -31,7 +31,8 @@ sdk/basyx/version.py
3131
compliance_tool/aas_compliance_tool/version.py
3232
server/app/version.py
3333

34-
# ignore the content of the server storage
34+
# Ignore the content of the server storage
35+
server/input/
3536
server/storage/
3637
test.py
3738
/storage/

README.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
# Eclipse BaSyx Python SDK
22

3-
(formerly known as PyI40AAS – Python Industry 4.0 Asset Administration Shell)
4-
53
The Eclipse BaSyx Python project focuses on providing a Python implementation of the Asset Administration Shell (AAS)
6-
for Industry 4.0 Systems.
7-
These are the currently implemented specifications:
4+
for Industry 4.0 Systems.
5+
6+
**Please note that the SDK version number is independent of the supported AAS versions!**
7+
8+
These are the implemented AAS specifications of the [current SDK release](https://github.com/eclipse-basyx/basyx-python-sdk/releases/latest), which can be also found on [PyPI](https://pypi.org/project/basyx-python-sdk/):
89

910
| Specification | Version |
1011
|---------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
@@ -14,6 +15,9 @@ These are the currently implemented specifications:
1415
| Part 3a: Data Specification IEC 61360 | [v3.0 (01003-a-3-0)](https://industrialdigitaltwin.org/wp-content/uploads/2023/04/IDTA-01003-a-3-0_SpecificationAssetAdministrationShell_Part3a_DataSpecification_IEC61360.pdf) |
1516
| Part 5: Package File Format (AASX) | [v3.0 (01005-3-0)](https://industrialdigitaltwin.org/wp-content/uploads/2023/04/IDTA-01005-3-0_SpecificationAssetAdministrationShell_Part5_AASXPackageFileFormat.pdf) |
1617

18+
If you need support to an older version of the specifications, please refer to our [prior releases](https://github.com/eclipse-basyx/basyx-python-sdk/releases).
19+
Each of them has a similar table at the top of the release notes.
20+
1721
## Features
1822
This repository is structured into separate packages.
1923
The `sdk` directory provides the AAS metamodel as Python objects and fundamental functionalities to handle AAS.

compliance_tool/aas_compliance_tool/compliance_check_aasx.py

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (c) 2025 the Eclipse BaSyx Authors
1+
# Copyright (c) 2026 the Eclipse BaSyx Authors
22
#
33
# This program and the accompanying materials are made available under the terms of the MIT License, available in
44
# the LICENSE file of this project.
@@ -31,7 +31,7 @@
3131

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

7373
try:
7474
# read given file
7575
state_manager.add_step('Read file')
76-
obj_store: model.DictObjectStore[model.Identifiable] = model.DictObjectStore()
76+
identifiable_store: model.DictIdentifiableStore[model.Identifiable] = model.DictIdentifiableStore()
7777
files = aasx.DictSupplementaryFileContainer()
78-
reader.read_into(obj_store, files)
78+
reader.read_into(identifiable_store, files)
7979
new_cp = reader.get_core_properties()
8080
state_manager.set_step_status(Status.SUCCESS)
8181
except (ValueError, KeyError) as error:
8282
logger.error(error)
8383
state_manager.set_step_status(Status.FAILED)
84-
return model.DictObjectStore(), aasx.DictSupplementaryFileContainer(), pyecma376_2.OPCCoreProperties()
84+
return model.DictIdentifiableStore(), aasx.DictSupplementaryFileContainer(), pyecma376_2.OPCCoreProperties()
8585
finally:
8686
reader.close()
8787

88-
return obj_store, files, new_cp
88+
return identifiable_store, files, new_cp
8989

9090

9191
def check_schema(file_path: str, state_manager: ComplianceToolStateManager) -> None:
@@ -174,7 +174,7 @@ def check_aas_example(file_path: str, state_manager: ComplianceToolStateManager,
174174
logger_example.propagate = False
175175
logger_example.setLevel(logging.INFO)
176176

177-
obj_store, files, cp_new = check_deserialization(file_path, state_manager)
177+
identifiable_store, files, cp_new = check_deserialization(file_path, state_manager)
178178

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

188188
state_manager.add_step('Check if data is equal to example data')
189189
example_data = create_example_aas_binding()
190-
checker.check_object_store(obj_store, example_data)
190+
checker.check_identifiable_store(identifiable_store, example_data)
191191
state_manager.add_log_records_from_data_checker(checker)
192192

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

239239
# Check if file in file object is the same
240240
list_of_id_shorts = ["ExampleSubmodelCollection", "ExampleFile"]
241-
obj = example_data.get_identifiable("https://acplt.org/Test_Submodel")
241+
identifiable = example_data.get_item("https://acplt.org/Test_Submodel")
242242
for id_short in list_of_id_shorts:
243-
obj = obj.get_referable(id_short)
244-
obj2 = obj_store.get_identifiable("https://acplt.org/Test_Submodel")
243+
identifiable = identifiable.get_referable(id_short)
244+
obj2 = identifiable_store.get_item("https://acplt.org/Test_Submodel")
245245
for id_short in list_of_id_shorts:
246246
obj2 = obj2.get_referable(id_short)
247247
try:
248-
sha_file = files.get_sha256(obj.value)
248+
sha_file = files.get_sha256(identifiable.value)
249249
except KeyError as error:
250250
state_manager.add_log_records_from_data_checker(checker2)
251251
logger.error(error)
252252
state_manager.set_step_status(Status.FAILED)
253253
return
254254

255-
checker2.check(sha_file == files.get_sha256(obj2.value), "File of {} must be {}.".format(obj.value, obj2.value),
256-
value=obj2.value)
255+
checker2.check(
256+
sha_file == files.get_sha256(obj2.value),
257+
"File of {} must be {}.".format(identifiable.value, obj2.value),
258+
value=obj2.value
259+
)
257260
state_manager.add_log_records_from_data_checker(checker2)
258261
if state_manager.status in (Status.FAILED, Status.NOT_EXECUTED):
259262
state_manager.set_step_status(Status.FAILED)
@@ -280,9 +283,9 @@ def check_aasx_files_equivalence(file_path_1: str, file_path_2: str, state_manag
280283
logger.propagate = False
281284
logger.setLevel(logging.INFO)
282285

283-
obj_store_1, files_1, cp_1 = check_deserialization(file_path_1, state_manager, 'first')
286+
identifiable_store_1, files_1, cp_1 = check_deserialization(file_path_1, state_manager, 'first')
284287

285-
obj_store_2, files_2, cp_2 = check_deserialization(file_path_2, state_manager, 'second')
288+
identifiable_store_2, files_2, cp_2 = check_deserialization(file_path_2, state_manager, 'second')
286289

287290
if state_manager.status is Status.FAILED:
288291
state_manager.add_step('Check if data in files are equal')
@@ -294,7 +297,7 @@ def check_aasx_files_equivalence(file_path_1: str, file_path_2: str, state_manag
294297
checker = AASDataChecker(raise_immediately=False, **kwargs)
295298
try:
296299
state_manager.add_step('Check if data in files are equal')
297-
checker.check_object_store(obj_store_1, obj_store_2)
300+
checker.check_identifiable_store(identifiable_store_1, identifiable_store_2)
298301
except (KeyError, AssertionError) as error:
299302
state_manager.set_step_status(Status.FAILED)
300303
logger.error(error)

0 commit comments

Comments
 (0)