Skip to content
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
9 changes: 0 additions & 9 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,6 @@ jobs:
- name: Check typing with MyPy
run: |
python -m mypy basyx test
- name: Check code style with PyCodestyle
run: |
python -m pycodestyle --count --max-line-length 120 basyx test

sdk-readme-codeblocks:
# This job runs the same static code analysis (mypy and pycodestyle) on the codeblocks in our docstrings.
Expand Down Expand Up @@ -265,9 +262,6 @@ jobs:
- name: Check typing with MyPy
run: |
python -m mypy aas_compliance_tool test
- name: Check code style with PyCodestyle
run: |
python -m pycodestyle --count --max-line-length 120 aas_compliance_tool test

compliance-tool-package:
# This job checks if we can build our compliance_tool package
Expand Down Expand Up @@ -316,9 +310,6 @@ jobs:
- name: Check typing with MyPy
run: |
python -m mypy app test
- name: Check code style with PyCodestyle
run: |
python -m pycodestyle --count --max-line-length 120 app test

server-repository-docker:
# This job checks if we can build our server package
Expand Down
7 changes: 5 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ before new code can be added:
- We run the developed unittests and aim for a code coverage of at least 80%.
- We perform static code analysis for type-checking and codestyle, not just in the code itself, but also in codeblocks
that are inside docstrings and the `README.md`.
- We apply a set of [ruff](https://docs.astral.sh/ruff/) linter rules (see [ruff.toml](ruff.toml)) to ensure a certain
codestyle and prevent issues / bad practices to arise.
- We check that the automatically generated developer documentation compiles.
- We check that the Python Versions we support match between the different subprojects in the monorepository and are
not End of Life.
Expand All @@ -164,8 +166,8 @@ pip install .[dev]

Running all checks:
```bash
ruff check
mypy basyx test
pycodestyle --max-line-length 120 basyx test
python -m unittest
coverage run --source basyx --branch -m unittest
coverage report -m
Expand All @@ -185,6 +187,7 @@ of it without error.
For that, you need to have Docker installed on your system.
In the directory with the `Dockerfile`:
```bash
ruff check
docker build -t basyx-python-server .
docker run --name basyx-python-server basyx-python-server
```
Expand All @@ -204,8 +207,8 @@ itself.

Then you can run the checks via:
```bash
ruff check
mypy basyx test
pycodestyle --max-line-length 120 basyx test
python -m unittest
coverage run --source basyx --branch -m unittest
coverage report -m
Expand Down
13 changes: 6 additions & 7 deletions compliance_tool/aas_compliance_tool/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,17 @@
"""
import argparse
import datetime

import logging

import pyecma376_2

from basyx.aas.adapter import aasx
from basyx.aas.adapter.xml import write_aas_xml_file
from aas_compliance_tool import compliance_check_xml as compliance_tool_xml, \
compliance_check_json as compliance_tool_json, \
compliance_check_aasx as compliance_tool_aasx
from basyx.aas.adapter.json import write_aas_json_file
from basyx.aas.examples.data import create_example, create_example_aas_binding, TEST_PDF_FILE
from basyx.aas.adapter.xml import write_aas_xml_file
from basyx.aas.examples.data import TEST_PDF_FILE, create_example, create_example_aas_binding

from aas_compliance_tool import compliance_check_aasx as compliance_tool_aasx
from aas_compliance_tool import compliance_check_json as compliance_tool_json
from aas_compliance_tool import compliance_check_xml as compliance_tool_xml
from aas_compliance_tool.state_manager import ComplianceToolStateManager, Status


Expand Down
9 changes: 3 additions & 6 deletions compliance_tool/aas_compliance_tool/compliance_check_aasx.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,15 @@
import datetime
import logging
from typing import Optional, Tuple, cast
import io
from lxml import etree # type: ignore

import pyecma376_2

from aas_compliance_tool import compliance_check_json, compliance_check_xml
from basyx.aas import model
from basyx.aas.adapter import aasx
from basyx.aas.adapter.xml import xml_deserialization
from basyx.aas.adapter.json import json_deserialization
from basyx.aas.examples.data import example_aas, create_example_aas_binding
from basyx.aas.adapter.xml import xml_deserialization
from basyx.aas.examples.data import create_example_aas_binding, example_aas
from basyx.aas.examples.data._helper import AASDataChecker, DataChecker

from aas_compliance_tool.state_manager import ComplianceToolStateManager, Status


Expand Down
9 changes: 4 additions & 5 deletions compliance_tool/aas_compliance_tool/compliance_check_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,14 @@
:class:`~basyx.aas.compliance_tool.state_manager.ComplianceToolStateManager` by adding new steps and associated
:class:`LogRecords <logging.LogRecord>`
"""
import os
import json
import logging
from typing import Optional, IO
from typing import Optional

from basyx.aas import (model)
from basyx.aas import model
from basyx.aas.adapter.json import json_deserialization
from basyx.aas.examples.data import example_aas, create_example
from basyx.aas.examples.data import create_example, example_aas
from basyx.aas.examples.data._helper import AASDataChecker

from aas_compliance_tool.state_manager import ComplianceToolStateManager, Status


Expand Down
5 changes: 2 additions & 3 deletions compliance_tool/aas_compliance_tool/compliance_check_xml.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,14 @@
:class:`~basyx.aas.compliance_tool.state_manager.ComplianceToolStateManager` by adding new steps and associated
:class:`LogRecords <logging.LogRecord>`
"""
import os
from lxml import etree # type: ignore
import logging
from typing import Optional

from basyx.aas import model
from basyx.aas.adapter.xml import xml_deserialization
from basyx.aas.examples.data import example_aas, create_example
from basyx.aas.examples.data import create_example, example_aas
from basyx.aas.examples.data._helper import AASDataChecker

from aas_compliance_tool.state_manager import ComplianceToolStateManager, Status


Expand Down
8 changes: 6 additions & 2 deletions compliance_tool/aas_compliance_tool/state_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@
This module defines a :class:`~.ComplianceToolStateManager` to store :class:`LogRecords <logging.LogRecord>`
for single steps in a compliance check of the compliance tool
"""
import logging
import enum
import logging
import pprint
from typing import List, Dict
from typing import Dict, List

from basyx.aas.examples.data._helper import DataChecker


Expand All @@ -25,6 +26,7 @@ class Status(enum.IntEnum):
:cvar FAILED:
:cvar NOT_EXECUTED:
"""

SUCCESS = 0
SUCCESS_WITH_WARNINGS = 1 # never used
FAILED = 2
Expand All @@ -39,6 +41,7 @@ class Step:
:ivar status: Status of the step from type Status
:ivar log_list: List of :class:`LogRecords <logging.LogRecord>` which belong to this step
"""

def __init__(self, name: str, status: Status, log_list: List[logging.LogRecord]):
self.name = name
self.status = status
Expand All @@ -65,6 +68,7 @@ class ComplianceToolStateManager(logging.Handler):

:ivar steps: List of :class:`Steps <.Step>`
"""

def __init__(self):
"""
steps: List of steps. Each step consist of a step name, a step status and LogRecords belong to to this step.
Expand Down
7 changes: 3 additions & 4 deletions compliance_tool/test/_test_helper.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import io
from typing import Literal, Type, Optional
import datetime
import io
import logging
from typing import Literal, Optional, Type

import pyecma376_2

from basyx.aas.examples.data import create_example_aas_binding, TEST_PDF_FILE
from basyx.aas.examples.data import TEST_PDF_FILE, create_example_aas_binding


def create_example_aas_core_properties() -> pyecma376_2.OPCCoreProperties:
Expand Down
3 changes: 1 addition & 2 deletions compliance_tool/test/test_aas_compliance_tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,11 @@
import datetime
import hashlib
import io
import os
import tempfile
import unittest
from contextlib import redirect_stderr, redirect_stdout
from io import StringIO
from unittest.mock import patch, ANY
from unittest.mock import ANY, patch

from aas_compliance_tool.cli import main, parse_cli_arguments
from basyx.aas import model
Expand Down
4 changes: 2 additions & 2 deletions compliance_tool/test/test_compliance_check_aasx.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
import unittest
from unittest import mock

from ._test_helper import create_example_aas_core_properties, create_read_into_mock
from aas_compliance_tool import compliance_check_aasx as compliance_tool
from aas_compliance_tool.state_manager import ComplianceToolStateManager, Status

from basyx.aas.examples.data._helper import CheckResult

from ._test_helper import create_example_aas_core_properties, create_read_into_mock


class ComplianceToolAASXTest(unittest.TestCase):

Expand Down
4 changes: 2 additions & 2 deletions compliance_tool/test/test_compliance_check_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
import unittest
from unittest import mock

from ._test_helper import create_mock_effect
from aas_compliance_tool import compliance_check_json as compliance_tool
from aas_compliance_tool.state_manager import ComplianceToolStateManager, Status

from basyx.aas.examples.data._helper import CheckResult

from ._test_helper import create_mock_effect


class ComplianceToolJsonTest(unittest.TestCase):

Expand Down
4 changes: 2 additions & 2 deletions compliance_tool/test/test_compliance_check_xml.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
import unittest
from unittest import mock

from ._test_helper import create_mock_effect
from aas_compliance_tool import compliance_check_xml as compliance_tool
from aas_compliance_tool.state_manager import ComplianceToolStateManager, Status

from basyx.aas.examples.data._helper import CheckResult

from ._test_helper import create_mock_effect


class ComplianceToolXmlTest(unittest.TestCase):

Expand Down
3 changes: 1 addition & 2 deletions compliance_tool/test/test_compliance_tool_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,13 @@
from typing import cast
from unittest.mock import patch

from aas_compliance_tool.cli import main
from basyx.aas import model
from basyx.aas.adapter import aasx
from basyx.aas.adapter.json import write_aas_json_file
from basyx.aas.adapter.xml import write_aas_xml_file
from basyx.aas.examples.data.example_aas import create_full_example

from aas_compliance_tool.cli import main


class ComplianceToolIntegrationTest(unittest.TestCase):

Expand Down
6 changes: 4 additions & 2 deletions etc/scripts/check_python_versions_coincide.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
This helper script checks if the Python versions defined in a `pyproject.toml` coincide with the given `min_version`
and `max_version` and returns an error if they don't.
"""
import re
import argparse
import re
import sys
from packaging.version import Version, InvalidVersion

from packaging.version import InvalidVersion, Version


def main(pyproject_toml_path: str, min_version: str, max_version: str) -> None:
# Load and check `requires-python` version from `pyproject.toml`
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 @@ -4,9 +4,11 @@
"""
import argparse
import sys
from datetime import datetime

import requests
from packaging.version import InvalidVersion
from datetime import datetime


def main(min_version: str, max_version: str) -> None:
# Fetch supported Python versions and check min/max versions
Expand Down
39 changes: 39 additions & 0 deletions ruff.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
line-length = 120 # matches the current pycodestyle --max-line-length 120
target-version = "py310" # matches X_PYTHON_MIN_VERSION in ci.yml

[format]
quote-style = "double"
indent-style = "space"
docstring-code-format = true


[lint]
select = [
"E", # pycodestyle errors
"W", # pycodestyle warnings
"RUF100", # unused noqa
"F5", # pyflakes: format strings
"COM818", # enforce trailing comma
"F7", # pyflakes: control flow (return/break/continue outside loop/func)
"D204", "D211", "D201", "D300", # basic docstring formatting
"I", # isort
"F8", # pyflakes: undefined/unused names
"F4", # pyflakes: imports/__future__
"PIE", # small readability improvements
]

# TODO: Revisit these
ignore = [
"F403", # star imports - high existing usage
"F405", # may-be-undefined from star imports
"N818", # Exception name should be named with Error suffix
"N", # pep8-naming
"B", # flake8-bugbear
"T20", # prevent native print() statements
"A", # prevent shadowing of python builtins
"FIX", # prevent the creation of T0DO / F1XME comments
"PYI", # typing best practices
# Evaluate if we want to use:
"S", # security related precautions
"BLE", # prevent unspecified excepts
]
13 changes: 9 additions & 4 deletions sdk/basyx/aas/adapter/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,18 @@
* :ref:`aasx <adapter.aasx>`: This package offers functions for reading and writing AASX-files.
"""

from pathlib import Path
from typing import Union

from basyx.aas.adapter.aasx import AASXReader, DictSupplementaryFileContainer
from basyx.aas.adapter.json import read_aas_json_file_into
from basyx.aas.adapter.xml import read_aas_xml_file_into
from basyx.aas.model.provider import DictIdentifiableStore
from pathlib import Path
from typing import Union


def load_directory(directory: Union[Path, str]) -> tuple[DictIdentifiableStore, DictSupplementaryFileContainer]:
def load_directory(
directory: Union[Path, str],
) -> tuple[DictIdentifiableStore, DictSupplementaryFileContainer]:
"""
Create a new :class:`~basyx.aas.model.provider.DictIdentifiableStore` and use it to load Asset Administration Shell
and Submodel files in ``AASX``, ``JSON`` and ``XML`` format from a given directory into memory. Additionally, load
Expand Down Expand Up @@ -46,6 +49,8 @@ def load_directory(directory: Union[Path, str]) -> tuple[DictIdentifiableStore,
read_aas_xml_file_into(dict_identifiable_store, f)
elif suffix == ".aasx":
with AASXReader(file) as reader:
reader.read_into(object_store=dict_identifiable_store, file_store=file_container)
reader.read_into(
object_store=dict_identifiable_store, file_store=file_container
)

return dict_identifiable_store, file_container
Loading
Loading