Skip to content

Commit 60612d2

Browse files
authored
Merge branch 'rwth-iat:main' into aas_manager/v30
2 parents f678e70 + 0927305 commit 60612d2

File tree

79 files changed

+1455
-1350
lines changed

Some content is hidden

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

79 files changed

+1455
-1350
lines changed

.github/workflows/ci.yml

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

55
env:
6-
X_PYTHON_VERSION: "3.10"
6+
X_PYTHON_VERSION: "3.12"
77

88
jobs:
99
test:
1010
runs-on: ubuntu-latest
1111
strategy:
1212
matrix:
13-
python-version: ["3.7", "3.9", "3.11"]
13+
python-version: ["3.8", "3.10", "3.12"]
1414
env:
1515
COUCHDB_ADMIN_PASSWORD: "yo0Quai3"
1616
services:
@@ -89,15 +89,33 @@ jobs:
8989
run: |
9090
codeblocks python README.md | python
9191
92+
docs:
93+
runs-on: ubuntu-latest
94+
95+
steps:
96+
- uses: actions/checkout@v2
97+
- name: Set up Python ${{ env.X_PYTHON_VERSION }}
98+
uses: actions/setup-python@v2
99+
with:
100+
python-version: ${{ env.X_PYTHON_VERSION }}
101+
- name: Install Python dependencies
102+
run: |
103+
python -m pip install --upgrade pip
104+
pip install -r requirements.txt
105+
pip install -r docs/add-requirements.txt
106+
- name: Check documentation for errors
107+
run: |
108+
SPHINXOPTS="-a -E -n -W --keep-going" make -C docs html
109+
92110
package:
93111
runs-on: ubuntu-latest
94112

95113
steps:
96114
- uses: actions/checkout@v2
97-
- name: Set up Python 3.10
115+
- name: Set up Python ${{ env.X_PYTHON_VERSION }}
98116
uses: actions/setup-python@v2
99117
with:
100-
python-version: "3.10"
118+
python-version: ${{ env.X_PYTHON_VERSION }}
101119
- name: Install dependencies
102120
run: |
103121
python -m pip install --upgrade pip

README.md

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,15 @@ SPDX-License-Identifier: MIT
4444
For more information, especially considering the licenses of included third-party works, please consult the `NOTICE`
4545
file.
4646

47+
## Release Schedule
48+
49+
The Eclipse BaSyx-Python SDK Team evaluates bi-monthly the newly added commits to the main branch towards the need
50+
of releasing a new version.
51+
If decided the changes warrant a release, it is initiated, using semantic versioning for the new release number.
52+
If the changes do not warrant a release, the decision is postponed to the next meeting.
53+
54+
Additionally, security fixes may be released at any point.
55+
4756

4857
## Dependencies
4958

@@ -60,12 +69,8 @@ dependencies (MIT License, Apache License, PSF License)
6069

6170
Development/testing/documentation/example dependencies (see `requirements.txt`):
6271
* `jsonschema` and its dependencies (MIT License, Apache License, PSF License)
63-
* `psutil` (BSD 3-clause License)
64-
* `Sphinx` and its dependencies (multiple licenses)
65-
* `sphinx-rtd-theme` and its dependencies
66-
* `sphinx-argparse` (MIT License)
6772

68-
Dependencies for building the documentation:
73+
Dependencies for building the documentation (see `docs/add-requirements.txt`):
6974
* `Sphinx` and its dependencies (BSD 2-clause License, MIT License, Apache License)
7075
* `sphinx-rtd-theme` and its dependencies (MIT License, PSF License)
7176
* `sphinx-argparse` (MIT License)

basyx/aas/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,5 @@
66
in 'adapter', you can find JSON and XML adapters to translate between BaSyx Python SDK objects and JSON/XML schemas;
77
and in 'util', some helpful functionality to actually use the AAS meta-model you created with 'model' is located.
88
"""
9+
10+
__version__ = "1.0.0"

basyx/aas/adapter/aasx.py

Lines changed: 90 additions & 86 deletions
Large diffs are not rendered by default.

basyx/aas/adapter/json/__init__.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,17 @@
44
This package contains functionality for serialization and deserialization of BaSyx Python SDK objects into/from JSON.
55
66
:ref:`json_serialization <adapter.json.json_serialization>`: The module offers a function to write an ObjectStore to a
7-
given file and therefore defines the custom JSONEncoder :class:`~.aas.adapter.json.json_serialization.AASToJsonEncoder`
8-
which handles encoding of all BaSyx Python SDK objects and their attributes by converting them into standard python
9-
objects.
7+
given file and therefore defines the custom JSONEncoder
8+
:class:`~basyx.aas.adapter.json.json_serialization.AASToJsonEncoder` which handles encoding of all BaSyx Python SDK
9+
objects and their attributes by converting them into standard python objects.
1010
1111
:ref:`json_deserialization <adapter.json.json_deserialization>`: The module implements custom JSONDecoder classes
12-
:class:`~aas.adapter.json.json_deserialization.AASFromJsonDecoder` and
13-
:class:`~aas.adapter.json.json_deserialization.StrictAASFromJsonDecoder`, that — when used with Python's `json`
14-
module — detect AAS objects in the parsed JSON and convert them into the corresponding BaSyx Python SDK object.
15-
A function :meth:`~aas.adapter.json.json_deserialization.read_aas_json_file` is provided to read all AAS objects
16-
within a JSON file and return them as BaSyx Python SDK objectstore.
12+
:class:`~basyx.aas.adapter.json.json_deserialization.AASFromJsonDecoder` and
13+
:class:`~basyx.aas.adapter.json.json_deserialization.StrictAASFromJsonDecoder`, that — when used with Python's
14+
:mod:`json` module — detect AAS objects in the parsed JSON and convert them into the corresponding BaSyx Python SDK
15+
object. A function :meth:`~basyx.aas.adapter.json.json_deserialization.read_aas_json_file` is provided to read all
16+
AAS objects within a JSON file and return them as BaSyx Python SDK
17+
:class:`ObjectStore <basyx.aas.model.provider.AbstractObjectStore>`.
1718
"""
1819
import os.path
1920

basyx/aas/adapter/json/json_deserialization.py

Lines changed: 49 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,24 @@
1010
Module for deserializing Asset Administration Shell data from the official JSON format
1111
1212
The module provides custom JSONDecoder classes :class:`~.AASFromJsonDecoder` and :class:`~.StrictAASFromJsonDecoder` to
13-
be used with the Python standard `json` module.
14-
15-
Furthermore it provides two classes :class:`~aas.adapter.json.json_deserialization.StrippedAASFromJsonDecoder` and
16-
:class:`~aas.adapter.json.json_deserialization.StrictStrippedAASFromJsonDecoder` for parsing stripped JSON objects,
17-
which are used in the http adapter (see https://git.rwth-aachen.de/acplt/pyi40aas/-/issues/91).
18-
The classes contain a custom :meth:`~aas.adapter.json.json_deserialization.AASFromJsonDecoder.object_hook` function
19-
to detect encoded AAS objects within the JSON data and convert them to BaSyx Python SDK objects while parsing.
20-
Additionally, there's the :meth:`~aas.adapter.json.json_deserialization.read_aas_json_file_into` function, that takes a
21-
complete AAS JSON file, reads its contents and stores the objects in the provided
22-
:class:`~aas.model.provider.AbstractObjectStore`. :meth:`~aas.adapter.json.json_deserialization.read_aas_json_file` is
23-
a wrapper for this function. Instead of storing the objects in a given :class:`~aas.model.provider.AbstractObjectStore`,
24-
it returns a :class:`~aas.model.provider.DictObjectStore` containing parsed objects.
25-
26-
The deserialization is performed in a bottom-up approach: The `object_hook()` method gets called for every parsed JSON
27-
object (as dict) and checks for existence of the `modelType` attribute. If it is present, the `AAS_CLASS_PARSERS` dict
28-
defines, which of the constructor methods of the class is to be used for converting the dict into an object. Embedded
29-
objects that should have a `modelType` themselves are expected to be converted already. Other embedded objects are
30-
converted using a number of helper constructor methods.
13+
be used with the Python standard :mod:`json` module.
14+
15+
Furthermore it provides two classes :class:`~basyx.aas.adapter.json.json_deserialization.StrippedAASFromJsonDecoder` and
16+
:class:`~basyx.aas.adapter.json.json_deserialization.StrictStrippedAASFromJsonDecoder` for parsing stripped
17+
JSON objects, which are used in the http adapter (see https://git.rwth-aachen.de/acplt/pyi40aas/-/issues/91).
18+
The classes contain a custom :meth:`~basyx.aas.adapter.json.json_deserialization.AASFromJsonDecoder.object_hook`
19+
function to detect encoded AAS objects within the JSON data and convert them to BaSyx Python SDK objects while parsing.
20+
Additionally, there's the :meth:`~basyx.aas.adapter.json.json_deserialization.read_aas_json_file_into` function, that
21+
takes a complete AAS JSON file, reads its contents and stores the objects in the provided
22+
:class:`~basyx.aas.model.provider.AbstractObjectStore`. :meth:`read_aas_json_file` is a wrapper for this function.
23+
Instead of storing the objects in a given :class:`~basyx.aas.model.provider.AbstractObjectStore`,
24+
it returns a :class:`~basyx.aas.model.provider.DictObjectStore` containing parsed objects.
25+
26+
The deserialization is performed in a bottom-up approach: The ``object_hook()`` method gets called for every parsed JSON
27+
object (as dict) and checks for existence of the ``modelType`` attribute. If it is present, the ``AAS_CLASS_PARSERS``
28+
dict defines, which of the constructor methods of the class is to be used for converting the dict into an object.
29+
Embedded objects that should have a ``modelType`` themselves are expected to be converted already.
30+
Other embedded objects are converted using a number of helper constructor methods.
3131
"""
3232
import base64
3333
import json
@@ -101,7 +101,7 @@ def _expect_type(object_: object, type_: Type, context: str, failsafe: bool) ->
101101

102102
class AASFromJsonDecoder(json.JSONDecoder):
103103
"""
104-
Custom JSONDecoder class to use the `json` module for deserializing Asset Administration Shell data from the
104+
Custom JSONDecoder class to use the :mod:`json` module for deserializing Asset Administration Shell data from the
105105
official JSON format
106106
107107
The class contains a custom :meth:`~.AASFromJsonDecoder.object_hook` function to detect encoded AAS objects within
@@ -113,17 +113,17 @@ class AASFromJsonDecoder(json.JSONDecoder):
113113
114114
data = json.loads(json_string, cls=AASFromJsonDecoder)
115115
116-
The `object_hook` function uses a set of `_construct_*()` methods, one for each
116+
The ``object_hook`` function uses a set of ``_construct_*()`` methods, one for each
117117
AAS object type to transform the JSON objects in to BaSyx Python SDK objects. These constructor methods are divided
118-
into two parts: "Helper Constructor Methods", that are used to construct AAS object types without a `modelType`
118+
into two parts: "Helper Constructor Methods", that are used to construct AAS object types without a ``modelType``
119119
attribute as embedded objects within other AAS objects, and "Direct Constructor Methods" for AAS object types *with*
120-
`modelType` attribute. The former are called from other constructor methods or utility methods based on the expected
121-
type of an attribute, the latter are called directly from the `object_hook()` function based on the `modelType`
122-
attribute.
120+
``modelType`` attribute. The former are called from other constructor methods or utility methods based on the
121+
expected type of an attribute, the latter are called directly from the ``object_hook()`` function based on the
122+
``modelType`` attribute.
123123
124124
This class may be subclassed to override some of the constructor functions, e.g. to construct objects of specialized
125-
subclasses of the BaSyx Python SDK object classes instead of these normal classes from the `model` package. To
126-
simplify this tasks, (nearly) all the constructor methods take a parameter `object_type` defaulting to the normal
125+
subclasses of the BaSyx Python SDK object classes instead of these normal classes from the ``model`` package. To
126+
simplify this tasks, (nearly) all the constructor methods take a parameter ``object_type`` defaulting to the normal
127127
BaSyx Python SDK object class, that can be overridden in a derived function:
128128
129129
.. code-block:: python
@@ -139,11 +139,11 @@ def _construct_submodel(cls, dct, object_class=EnhancedSubmodel):
139139
return super()._construct_submodel(dct, object_class=object_class)
140140
141141
142-
:cvar failsafe: If `True` (the default), don't raise Exceptions for missing attributes and wrong types, but instead
143-
skip defective objects and use logger to output warnings. Use StrictAASFromJsonDecoder for a
142+
:cvar failsafe: If ``True`` (the default), don't raise Exceptions for missing attributes and wrong types, but
143+
instead skip defective objects and use logger to output warnings. Use StrictAASFromJsonDecoder for a
144144
non-failsafe version.
145-
:cvar stripped: If `True`, the JSON objects will be parsed in a stripped manner, excluding some attributes.
146-
Defaults to `False`.
145+
:cvar stripped: If ``True``, the JSON objects will be parsed in a stripped manner, excluding some attributes.
146+
Defaults to ``False``.
147147
See https://git.rwth-aachen.de/acplt/pyi40aas/-/issues/91
148148
"""
149149
failsafe = True
@@ -160,10 +160,10 @@ def object_hook(cls, dct: Dict[str, object]) -> object:
160160
return dct
161161

162162
# The following dict specifies a constructor method for all AAS classes that may be identified using the
163-
# `modelType` attribute in their JSON representation. Each of those constructor functions takes the JSON
163+
# ``modelType`` attribute in their JSON representation. Each of those constructor functions takes the JSON
164164
# representation of an object and tries to construct a Python object from it. Embedded objects that have a
165165
# modelType themselves are expected to be converted to the correct PythonType already. Additionally, each
166-
# function takes a bool parameter `failsafe`, which indicates weather to log errors and skip defective objects
166+
# function takes a bool parameter ``failsafe``, which indicates weather to log errors and skip defective objects
167167
# instead of raising an Exception.
168168
AAS_CLASS_PARSERS: Dict[str, Callable[[Dict[str, object]], object]] = {
169169
'AssetAdministrationShell': cls._construct_asset_administration_shell,
@@ -281,7 +281,7 @@ def _get_kind(cls, dct: Dict[str, object]) -> model.ModellingKind:
281281
Utility method to get the kind of an HasKind object from its JSON representation.
282282
283283
:param dct: The object's dict representation from JSON
284-
:return: The object's `kind` value
284+
:return: The object's ``kind`` value
285285
"""
286286
return MODELLING_KIND_INVERSE[_get_ts(dct, "kind", str)] if 'kind' in dct else model.ModellingKind.INSTANCE
287287

@@ -366,8 +366,8 @@ def _construct_administrative_information(
366366
@classmethod
367367
def _construct_operation_variable(cls, dct: Dict[str, object]) -> model.SubmodelElement:
368368
"""
369-
Since we don't implement `OperationVariable`, this constructor discards the wrapping `OperationVariable` object
370-
and just returns the contained :class:`~aas.model.submodel.SubmodelElement`.
369+
Since we don't implement ``OperationVariable``, this constructor discards the wrapping ``OperationVariable``
370+
object and just returns the contained :class:`~basyx.aas.model.submodel.SubmodelElement`.
371371
"""
372372
# TODO: remove the following type: ignore comments when mypy supports abstract types for Type[T]
373373
# see https://github.com/python/mypy/issues/5374
@@ -750,7 +750,7 @@ class StrictAASFromJsonDecoder(AASFromJsonDecoder):
750750
A strict version of the AASFromJsonDecoder class for deserializing Asset Administration Shell data from the
751751
official JSON format
752752
753-
This version has set `failsafe = False`, which will lead to Exceptions raised for every missing attribute or wrong
753+
This version has set ``failsafe = False``, which will lead to Exceptions raised for every missing attribute or wrong
754754
object type.
755755
"""
756756
failsafe = False
@@ -776,8 +776,8 @@ def _select_decoder(failsafe: bool, stripped: bool, decoder: Optional[Type[AASFr
776776
Returns the correct decoder based on the parameters failsafe and stripped. If a decoder class is given, failsafe
777777
and stripped are ignored.
778778
779-
:param failsafe: If `True`, a failsafe decoder is selected. Ignored if a decoder class is specified.
780-
:param stripped: If `True`, a decoder for parsing stripped JSON objects is selected. Ignored if a decoder class is
779+
:param failsafe: If ``True``, a failsafe decoder is selected. Ignored if a decoder class is specified.
780+
:param stripped: If ``True``, a decoder for parsing stripped JSON objects is selected. Ignored if a decoder class is
781781
specified.
782782
:param decoder: Is returned, if specified.
783783
:return: An :class:`~.AASFromJsonDecoder` (sub)class.
@@ -801,20 +801,20 @@ def read_aas_json_file_into(object_store: model.AbstractObjectStore, file: IO, r
801801
Read an Asset Administration Shell JSON file according to 'Details of the Asset Administration Shell', chapter 5.5
802802
into a given object store.
803803
804-
:param object_store: The :class:`ObjectStore <aas.model.provider.AbstractObjectStore>` in which the identifiable
805-
objects should be stored
804+
:param object_store: The :class:`ObjectStore <basyx.aas.model.provider.AbstractObjectStore>` in which the
805+
identifiable objects should be stored
806806
:param file: A file-like object to read the JSON-serialized data from
807807
:param replace_existing: Whether to replace existing objects with the same identifier in the object store or not
808808
:param ignore_existing: Whether to ignore existing objects (e.g. log a message) or raise an error.
809-
This parameter is ignored if replace_existing is `True`.
810-
:param failsafe: If `True`, the document is parsed in a failsafe way: Missing attributes and elements are logged
809+
This parameter is ignored if replace_existing is ``True``.
810+
:param failsafe: If ``True``, the document is parsed in a failsafe way: Missing attributes and elements are logged
811811
instead of causing exceptions. Defect objects are skipped.
812812
This parameter is ignored if a decoder class is specified.
813-
:param stripped: If `True`, stripped JSON objects are parsed.
813+
:param stripped: If ``True``, stripped JSON objects are parsed.
814814
See https://git.rwth-aachen.de/acplt/pyi40aas/-/issues/91
815815
This parameter is ignored if a decoder class is specified.
816816
:param decoder: The decoder class used to decode the JSON objects
817-
:return: A set of :class:`Identifiers <aas.model.base.Identifier>` that were added to object_store
817+
:return: A set of :class:`Identifiers <basyx.aas.model.base.Identifier>` that were added to object_store
818818
"""
819819
ret: Set[model.Identifier] = set()
820820
decoder_ = _select_decoder(failsafe, stripped, decoder)
@@ -866,13 +866,13 @@ def read_aas_json_file_into(object_store: model.AbstractObjectStore, file: IO, r
866866

867867
def read_aas_json_file(file: IO, **kwargs) -> model.DictObjectStore[model.Identifiable]:
868868
"""
869-
A wrapper of :meth:`~aas.adapter.json.json_deserialization.read_aas_json_file_into`, that reads all objects in an
870-
empty :class:`~aas.model.provider.DictObjectStore`. This function supports the same keyword arguments as
871-
:meth:`~aas.adapter.json.json_deserialization.read_aas_json_file_into`.
869+
A wrapper of :meth:`~basyx.aas.adapter.json.json_deserialization.read_aas_json_file_into`, that reads all objects
870+
in an empty :class:`~basyx.aas.model.provider.DictObjectStore`. This function supports the same keyword arguments as
871+
:meth:`~basyx.aas.adapter.json.json_deserialization.read_aas_json_file_into`.
872872
873873
:param file: A filename or file-like object to read the JSON-serialized data from
874-
:param kwargs: Keyword arguments passed to :meth:`~aas.adapter.json.json_deserialization.read_aas_json_file_into`
875-
:return: A :class:`~aas.model.provider.DictObjectStore` containing all AAS objects from the JSON file
874+
:param kwargs: Keyword arguments passed to :meth:`read_aas_json_file_into`
875+
:return: A :class:`~basyx.aas.model.provider.DictObjectStore` containing all AAS objects from the JSON file
876876
"""
877877
object_store: model.DictObjectStore[model.Identifiable] = model.DictObjectStore()
878878
read_aas_json_file_into(object_store, file, **kwargs)

0 commit comments

Comments
 (0)