aas-http-client 0.3.1__tar.gz → 0.3.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {aas_http_client-0.3.1 → aas_http_client-0.3.3}/PKG-INFO +1 -1
- {aas_http_client-0.3.1 → aas_http_client-0.3.3}/aas_http_client/client.py +55 -17
- {aas_http_client-0.3.1 → aas_http_client-0.3.3}/aas_http_client/wrapper/sdk_wrapper.py +44 -22
- {aas_http_client-0.3.1 → aas_http_client-0.3.3}/aas_http_client.egg-info/PKG-INFO +1 -1
- {aas_http_client-0.3.1 → aas_http_client-0.3.3}/pyproject.toml +1 -1
- {aas_http_client-0.3.1 → aas_http_client-0.3.3}/tests/test_client.py +205 -18
- {aas_http_client-0.3.1 → aas_http_client-0.3.3}/tests/test_wrapper.py +232 -22
- {aas_http_client-0.3.1 → aas_http_client-0.3.3}/LICENSE +0 -0
- {aas_http_client-0.3.1 → aas_http_client-0.3.3}/README.md +0 -0
- {aas_http_client-0.3.1 → aas_http_client-0.3.3}/aas_http_client/__init__.py +0 -0
- {aas_http_client-0.3.1 → aas_http_client-0.3.3}/aas_http_client/core/encoder.py +0 -0
- {aas_http_client-0.3.1 → aas_http_client-0.3.3}/aas_http_client/core/version_check.py +0 -0
- {aas_http_client-0.3.1 → aas_http_client-0.3.3}/aas_http_client/demo/demo_process.py +0 -0
- {aas_http_client-0.3.1 → aas_http_client-0.3.3}/aas_http_client/demo/logging_handler.py +0 -0
- {aas_http_client-0.3.1 → aas_http_client-0.3.3}/aas_http_client/utilities/__init__.py +0 -0
- {aas_http_client-0.3.1 → aas_http_client-0.3.3}/aas_http_client/utilities/model_builder.py +0 -0
- {aas_http_client-0.3.1 → aas_http_client-0.3.3}/aas_http_client.egg-info/SOURCES.txt +0 -0
- {aas_http_client-0.3.1 → aas_http_client-0.3.3}/aas_http_client.egg-info/dependency_links.txt +0 -0
- {aas_http_client-0.3.1 → aas_http_client-0.3.3}/aas_http_client.egg-info/requires.txt +0 -0
- {aas_http_client-0.3.1 → aas_http_client-0.3.3}/aas_http_client.egg-info/top_level.txt +0 -0
- {aas_http_client-0.3.1 → aas_http_client-0.3.3}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: aas-http-client
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.3
|
|
4
4
|
Summary: Generic python HTTP client for communication with various types of AAS servers
|
|
5
5
|
Author-email: Daniel Klein <daniel.klein@em.ag>
|
|
6
6
|
License: # :em engineering methods AG Software License
|
|
@@ -4,6 +4,7 @@ import json
|
|
|
4
4
|
import logging
|
|
5
5
|
import time
|
|
6
6
|
from pathlib import Path
|
|
7
|
+
from typing import Any
|
|
7
8
|
|
|
8
9
|
import basyx.aas.adapter.json
|
|
9
10
|
import basyx.aas.adapter.json.json_serialization as js
|
|
@@ -26,7 +27,7 @@ STATUS_CODE_404 = 404
|
|
|
26
27
|
HEADERS = {"Content-Type": "application/json"}
|
|
27
28
|
|
|
28
29
|
|
|
29
|
-
def log_response_errors(response: Response):
|
|
30
|
+
def log_response_errors(response: Response): # noqa: C901
|
|
30
31
|
"""Create error messages from the response and log them.
|
|
31
32
|
|
|
32
33
|
:param response: response
|
|
@@ -561,6 +562,32 @@ class AasHttpClient(BaseModel):
|
|
|
561
562
|
|
|
562
563
|
return True
|
|
563
564
|
|
|
565
|
+
def patch_submodel_element_by_path_value_only_submodel_repo(self, submodel_id: str, submodel_element_path: str, value: str) -> bool:
|
|
566
|
+
"""Updates the value of an existing SubmodelElement.
|
|
567
|
+
|
|
568
|
+
:param submodel_id: Encoded ID of the Submodel to update submodel element for
|
|
569
|
+
:param submodel_element_path: Path of the Submodel element to update
|
|
570
|
+
:param value: Submodel element value to update as string
|
|
571
|
+
:return: True if the patch was successful, False otherwise
|
|
572
|
+
"""
|
|
573
|
+
decoded_submodel_id: str = decode_base_64(submodel_id)
|
|
574
|
+
|
|
575
|
+
url = f"{self.base_url}/submodels/{decoded_submodel_id}/submodel-elements/{submodel_element_path}/$value"
|
|
576
|
+
|
|
577
|
+
try:
|
|
578
|
+
response = self._session.patch(url, headers=HEADERS, json=value, timeout=self.time_out)
|
|
579
|
+
logger.debug(f"Call REST API url '{response.url}'")
|
|
580
|
+
|
|
581
|
+
if response.status_code != STATUS_CODE_204:
|
|
582
|
+
log_response_errors(response)
|
|
583
|
+
return False
|
|
584
|
+
|
|
585
|
+
except requests.exceptions.RequestException as e:
|
|
586
|
+
logger.error(f"Error call REST API: {e}")
|
|
587
|
+
return False
|
|
588
|
+
|
|
589
|
+
return True
|
|
590
|
+
|
|
564
591
|
|
|
565
592
|
# endregion
|
|
566
593
|
|
|
@@ -577,19 +604,19 @@ def create_client_by_url(
|
|
|
577
604
|
connection_time_out: int = 60,
|
|
578
605
|
ssl_verify: str = True, # noqa: FBT002
|
|
579
606
|
) -> AasHttpClient | None:
|
|
580
|
-
"""Create a
|
|
607
|
+
"""Create a HTTP client for a AAS server connection from the given parameters.
|
|
581
608
|
|
|
582
|
-
:param base_url:
|
|
583
|
-
:param username:
|
|
584
|
-
:param password:
|
|
609
|
+
:param base_url: Base URL of the AAS server, e.g. "http://basyx_python_server:80/"_
|
|
610
|
+
:param username: Username for the AAS server, defaults to ""_
|
|
611
|
+
:param password: Password for the AAS server, defaults to ""_
|
|
585
612
|
:param http_proxy: http proxy URL, defaults to ""_
|
|
586
613
|
:param https_proxy: https proxy URL, defaults to ""_
|
|
587
|
-
:param time_out:
|
|
588
|
-
:param connection_time_out:
|
|
589
|
-
:param ssl_verify:
|
|
590
|
-
:return: An instance of
|
|
614
|
+
:param time_out: Timeout for the API calls, defaults to 200
|
|
615
|
+
:param connection_time_out: Timeout for the connection to the API, defaults to 60
|
|
616
|
+
:param ssl_verify: Whether to verify SSL certificates, defaults to True
|
|
617
|
+
:return: An instance of Http client initialized with the provided parameters.
|
|
591
618
|
"""
|
|
592
|
-
logger.info(f"Create
|
|
619
|
+
logger.info(f"Create AAS server http client from URL '{base_url}'")
|
|
593
620
|
config_dict: dict[str, str] = {}
|
|
594
621
|
config_dict["base_url"] = base_url
|
|
595
622
|
config_dict["username"] = username
|
|
@@ -598,19 +625,31 @@ def create_client_by_url(
|
|
|
598
625
|
config_dict["time_out"] = time_out
|
|
599
626
|
config_dict["connection_time_out"] = connection_time_out
|
|
600
627
|
config_dict["ssl_verify"] = ssl_verify
|
|
601
|
-
|
|
628
|
+
return create_client_by_dict(config_dict, password)
|
|
629
|
+
|
|
630
|
+
|
|
631
|
+
def create_client_by_dict(configuration: dict, password: str = "") -> AasHttpClient | None:
|
|
632
|
+
"""Create a HTTP client for a AAS server connection from the given configuration.
|
|
633
|
+
|
|
634
|
+
:param configuration: Dictionary containing the BaSyx server connection settings.
|
|
635
|
+
:param password: Password for the AAS server, defaults to ""_
|
|
636
|
+
:return: An instance of Http client initialized with the provided parameters.
|
|
637
|
+
"""
|
|
638
|
+
logger.info(f"Create AAS server http client from configuration '{configuration}'")
|
|
639
|
+
config_string = json.dumps(configuration, indent=4)
|
|
640
|
+
|
|
602
641
|
return _create_client(config_string, password)
|
|
603
642
|
|
|
604
643
|
|
|
605
644
|
def create_client_by_config(config_file: Path, password: str = "") -> AasHttpClient | None:
|
|
606
|
-
"""Create a
|
|
645
|
+
"""Create a HTTP client for a AAS server connection from a given configuration file.
|
|
607
646
|
|
|
608
|
-
:param config_file: Path to the configuration file containing the
|
|
647
|
+
:param config_file: Path to the configuration file containing the AAS server connection settings.
|
|
609
648
|
:param password: password for the BaSyx server interface client, defaults to ""_
|
|
610
|
-
:return: An instance of
|
|
649
|
+
:return: An instance of Http client initialized with the provided parameters.
|
|
611
650
|
"""
|
|
612
651
|
config_file = config_file.resolve()
|
|
613
|
-
logger.info(f"Create AAS
|
|
652
|
+
logger.info(f"Create AAS server http client from configuration file '{config_file}'")
|
|
614
653
|
if not config_file.exists():
|
|
615
654
|
config_string = "{}"
|
|
616
655
|
logger.warning(f"Configuration file '{config_file}' not found. Using default configuration.")
|
|
@@ -623,8 +662,7 @@ def create_client_by_config(config_file: Path, password: str = "") -> AasHttpCli
|
|
|
623
662
|
|
|
624
663
|
def _create_client(config_string: str, password) -> AasHttpClient | None:
|
|
625
664
|
try:
|
|
626
|
-
|
|
627
|
-
client = AasHttpClient(**connection_settings.model_dump())
|
|
665
|
+
client = AasHttpClient.model_validate_json(config_string)
|
|
628
666
|
except ValidationError as ve:
|
|
629
667
|
raise ValidationError(f"Invalid BaSyx server connection file: {ve}") from ve
|
|
630
668
|
|
|
@@ -19,6 +19,20 @@ class SdkWrapper:
|
|
|
19
19
|
_client: AasHttpClient = None
|
|
20
20
|
base_url: str = ""
|
|
21
21
|
|
|
22
|
+
def __init__(self, config_string: str, password: str = ""):
|
|
23
|
+
"""Initializes the wrapper with the given configuration.
|
|
24
|
+
|
|
25
|
+
:param config_string: Configuration string for the BaSyx server connection.
|
|
26
|
+
:param password: Password for the BaSyx server interface client, defaults to "".
|
|
27
|
+
"""
|
|
28
|
+
client = _create_client(config_string, password)
|
|
29
|
+
|
|
30
|
+
if not client:
|
|
31
|
+
raise ValueError("Failed to create AAS HTTP client with the provided configuration.")
|
|
32
|
+
|
|
33
|
+
self._client = client
|
|
34
|
+
self.base_url = client.base_url
|
|
35
|
+
|
|
22
36
|
# region shells
|
|
23
37
|
|
|
24
38
|
def post_asset_administration_shell(self, aas: model.AssetAdministrationShell) -> model.AssetAdministrationShell | None:
|
|
@@ -261,11 +275,24 @@ class SdkWrapper:
|
|
|
261
275
|
:return: Submodel element object or None if an error occurred
|
|
262
276
|
"""
|
|
263
277
|
content: dict = self._client.get_submodel_element_by_path_submodel_repo(submodel_id, submodel_element_path)
|
|
278
|
+
print(content)
|
|
264
279
|
return _to_object(content)
|
|
265
280
|
|
|
281
|
+
def patch_submodel_element_by_path_value_only_submodel_repo(self, submodel_id: str, submodel_element_path: str, value: str) -> bool:
|
|
282
|
+
"""Updates the value of an existing SubmodelElement.
|
|
283
|
+
|
|
284
|
+
:param submodel_id: Encoded ID of the Submodel to update submodel element for
|
|
285
|
+
:param submodel_element_path: Path of the Submodel element to update
|
|
286
|
+
:param value: Submodel element value to update as string
|
|
287
|
+
:return: True if the patch was successful, False otherwise
|
|
288
|
+
"""
|
|
289
|
+
return self._client.patch_submodel_element_by_path_value_only_submodel_repo(submodel_id, submodel_element_path, value)
|
|
290
|
+
|
|
266
291
|
|
|
267
292
|
# endregion
|
|
268
293
|
|
|
294
|
+
# region utils
|
|
295
|
+
|
|
269
296
|
|
|
270
297
|
def _to_object(content: dict) -> Any | None:
|
|
271
298
|
try:
|
|
@@ -287,6 +314,8 @@ def _to_dict(object: Any) -> dict | None:
|
|
|
287
314
|
return None
|
|
288
315
|
|
|
289
316
|
|
|
317
|
+
# endregion
|
|
318
|
+
|
|
290
319
|
# region wrapper
|
|
291
320
|
|
|
292
321
|
|
|
@@ -300,7 +329,7 @@ def create_wrapper_by_url(
|
|
|
300
329
|
connection_time_out: int = 60,
|
|
301
330
|
ssl_verify: str = True, # noqa: FBT002
|
|
302
331
|
) -> SdkWrapper | None:
|
|
303
|
-
"""Create a wrapper for
|
|
332
|
+
"""Create a wrapper for a AAS server connection from the given parameters.
|
|
304
333
|
|
|
305
334
|
:param base_url: base URL of the BaSyx server, e.g. "http://basyx_python_server:80/"_
|
|
306
335
|
:param username: username for the BaSyx server interface client, defaults to ""_
|
|
@@ -312,7 +341,7 @@ def create_wrapper_by_url(
|
|
|
312
341
|
:param ssl_verify: whether to verify SSL certificates, defaults to True
|
|
313
342
|
:return: An instance of SdkWrapper initialized with the provided parameters.
|
|
314
343
|
"""
|
|
315
|
-
logger.info(f"Create
|
|
344
|
+
logger.info(f"Create AAS server wrapper from URL '{base_url}'")
|
|
316
345
|
config_dict: dict[str, str] = {}
|
|
317
346
|
config_dict["base_url"] = base_url
|
|
318
347
|
config_dict["username"] = username
|
|
@@ -321,43 +350,36 @@ def create_wrapper_by_url(
|
|
|
321
350
|
config_dict["time_out"] = time_out
|
|
322
351
|
config_dict["connection_time_out"] = connection_time_out
|
|
323
352
|
config_dict["ssl_verify"] = ssl_verify
|
|
324
|
-
|
|
353
|
+
return create_wrapper_by_dict(config_dict, password)
|
|
325
354
|
|
|
326
|
-
wrapper = SdkWrapper()
|
|
327
|
-
client = _create_client(config_string, password)
|
|
328
355
|
|
|
329
|
-
|
|
330
|
-
|
|
356
|
+
def create_wrapper_by_dict(configuration: dict, password: str = "") -> SdkWrapper | None:
|
|
357
|
+
"""Create a wrapper for a AAS server connection from the given configuration.
|
|
331
358
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
return
|
|
359
|
+
:param config: Dictionary containing the BaSyx server connection settings.
|
|
360
|
+
:param password: Password for the BaSyx server interface client, defaults to "".
|
|
361
|
+
:return: An instance of SdkWrapper initialized with the provided parameters.
|
|
362
|
+
"""
|
|
363
|
+
logger.info(f"Create AAS server wrapper from configuration '{configuration}'")
|
|
364
|
+
config_string = json.dumps(configuration, indent=4)
|
|
365
|
+
return SdkWrapper(config_string, password)
|
|
335
366
|
|
|
336
367
|
|
|
337
368
|
def create_wrapper_by_config(config_file: Path, password: str = "") -> SdkWrapper | None:
|
|
338
|
-
"""Create a wrapper for
|
|
369
|
+
"""Create a wrapper for a AAS server connection from a given configuration file.
|
|
339
370
|
|
|
340
371
|
:param config_file: Path to the configuration file containing the BaSyx server connection settings.
|
|
341
372
|
:param password: password for the BaSyx server interface client, defaults to ""_
|
|
342
373
|
:return: An instance of SdkWrapper initialized with the provided parameters.
|
|
343
374
|
"""
|
|
344
|
-
logger.info(f"Create
|
|
375
|
+
logger.info(f"Create AAS wrapper client from configuration file '{config_file}'")
|
|
345
376
|
if not config_file.exists():
|
|
346
377
|
config_string = "{}"
|
|
347
378
|
logger.warning(f"Configuration file '{config_file}' not found. Using default config.")
|
|
348
379
|
else:
|
|
349
380
|
config_string = config_file.read_text(encoding="utf-8")
|
|
350
381
|
logger.debug(f"Configuration file '{config_file}' found.")
|
|
351
|
-
|
|
352
|
-
wrapper = SdkWrapper()
|
|
353
|
-
client = _create_client(config_string, password)
|
|
354
|
-
|
|
355
|
-
if not client:
|
|
356
|
-
return None
|
|
357
|
-
|
|
358
|
-
wrapper._client = client
|
|
359
|
-
wrapper.base_url = client.base_url
|
|
360
|
-
return wrapper
|
|
382
|
+
return SdkWrapper(config_string, password)
|
|
361
383
|
|
|
362
384
|
|
|
363
385
|
# endregion
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: aas-http-client
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.3
|
|
4
4
|
Summary: Generic python HTTP client for communication with various types of AAS servers
|
|
5
5
|
Author-email: Daniel Klein <daniel.klein@em.ag>
|
|
6
6
|
License: # :em engineering methods AG Software License
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "aas-http-client"
|
|
7
|
-
version = "0.3.
|
|
7
|
+
version = "0.3.3"
|
|
8
8
|
description = "Generic python HTTP client for communication with various types of AAS servers"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { file = "LICENSE" }
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import pytest
|
|
2
2
|
from pathlib import Path
|
|
3
|
-
from aas_http_client.client import create_client_by_config, AasHttpClient
|
|
3
|
+
from aas_http_client.client import create_client_by_config, AasHttpClient, create_client_by_dict, create_client_by_url
|
|
4
4
|
from basyx.aas import model
|
|
5
5
|
import aas_http_client.utilities.model_builder as model_builder
|
|
6
6
|
import json
|
|
@@ -13,9 +13,13 @@ PYTHON_SERVER_PORTS = [8080, 80]
|
|
|
13
13
|
CONFIG_FILES = [
|
|
14
14
|
"./tests/server_configs/test_dotnet_server_config.json",
|
|
15
15
|
"./tests/server_configs/test_java_server_config.json",
|
|
16
|
-
"./tests/server_configs/test_python_server_config.json"
|
|
16
|
+
"./tests/server_configs/test_python_server_config.json"
|
|
17
17
|
]
|
|
18
18
|
|
|
19
|
+
# CONFIG_FILES = [
|
|
20
|
+
# "./tests/server_configs/test_dotnet_server_config_local.json",
|
|
21
|
+
# ]
|
|
22
|
+
|
|
19
23
|
@pytest.fixture(params=CONFIG_FILES, scope="module")
|
|
20
24
|
def client(request) -> AasHttpClient:
|
|
21
25
|
try:
|
|
@@ -35,9 +39,24 @@ def client(request) -> AasHttpClient:
|
|
|
35
39
|
return client
|
|
36
40
|
|
|
37
41
|
@pytest.fixture(scope="module")
|
|
38
|
-
def
|
|
42
|
+
def shared_sme_string() -> model.Property:
|
|
43
|
+
# create a Submodel
|
|
44
|
+
return model_builder.create_base_submodel_element_Property("sme_property_string", model.datatypes.String, "Sample String Value")
|
|
45
|
+
|
|
46
|
+
@pytest.fixture(scope="module")
|
|
47
|
+
def shared_sme_bool() -> model.Property:
|
|
39
48
|
# create a Submodel
|
|
40
|
-
return model_builder.create_base_submodel_element_Property("
|
|
49
|
+
return model_builder.create_base_submodel_element_Property("sme_property_bool", model.datatypes.Boolean, True)
|
|
50
|
+
|
|
51
|
+
@pytest.fixture(scope="module")
|
|
52
|
+
def shared_sme_int() -> model.Property:
|
|
53
|
+
# create a Submodel
|
|
54
|
+
return model_builder.create_base_submodel_element_Property("sme_property_int", model.datatypes.Integer, 262)
|
|
55
|
+
|
|
56
|
+
@pytest.fixture(scope="module")
|
|
57
|
+
def shared_sme_float() -> model.Property:
|
|
58
|
+
# create a Submodel
|
|
59
|
+
return model_builder.create_base_submodel_element_Property("sme_property_float", model.datatypes.Float, 262.3)
|
|
41
60
|
|
|
42
61
|
@pytest.fixture(scope="module")
|
|
43
62
|
def shared_sm() -> model.Submodel:
|
|
@@ -54,6 +73,21 @@ def shared_aas(shared_sm: model.Submodel) -> model.AssetAdministrationShell:
|
|
|
54
73
|
|
|
55
74
|
return aas
|
|
56
75
|
|
|
76
|
+
def test_000a_create_client_by_url(client: AasHttpClient):
|
|
77
|
+
base_url: str = client.base_url
|
|
78
|
+
new_client: AasHttpClient = create_client_by_url(base_url=base_url)
|
|
79
|
+
assert new_client is not None
|
|
80
|
+
|
|
81
|
+
def test_000b_create_client_by_dict(client: AasHttpClient):
|
|
82
|
+
base_url: str = client.base_url
|
|
83
|
+
|
|
84
|
+
config_dict: dict = {
|
|
85
|
+
"base_url": base_url
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
new_client: AasHttpClient = create_client_by_dict(configuration=config_dict)
|
|
89
|
+
assert new_client is not None
|
|
90
|
+
|
|
57
91
|
def test_001a_connect(client: AasHttpClient):
|
|
58
92
|
assert client is not None
|
|
59
93
|
|
|
@@ -262,7 +296,7 @@ def test_012_patch_submodel_by_id(client: AasHttpClient, shared_sm: model.Submod
|
|
|
262
296
|
# NOTE: Basyx java and python server do not provide this endpoint
|
|
263
297
|
assert not result
|
|
264
298
|
else:
|
|
265
|
-
assert result
|
|
299
|
+
assert result is True
|
|
266
300
|
|
|
267
301
|
get_result = client.get_submodel_by_id(shared_sm.id)
|
|
268
302
|
assert get_result is not None
|
|
@@ -319,7 +353,7 @@ def test_014_put_submodels_by_id(client: AasHttpClient, shared_sm: model.Submode
|
|
|
319
353
|
|
|
320
354
|
result = client.put_submodels_by_id(shared_sm.id, sm_data)
|
|
321
355
|
|
|
322
|
-
assert result
|
|
356
|
+
assert result is True
|
|
323
357
|
|
|
324
358
|
get_result = client.get_submodel_by_id(shared_sm.id)
|
|
325
359
|
assert get_result is not None
|
|
@@ -341,33 +375,186 @@ def test_015_get_all_submodel_elements_submodel_repository(client: AasHttpClient
|
|
|
341
375
|
assert submodel_elements is not None
|
|
342
376
|
assert len(submodel_elements.get("result", [])) == 0
|
|
343
377
|
|
|
344
|
-
def
|
|
345
|
-
sme_data_string = json.dumps(
|
|
378
|
+
def test_016a_post_submodel_element_submodel_repo(client: AasHttpClient, shared_sm: model.Submodel, shared_sme_string: model.Property):
|
|
379
|
+
sme_data_string = json.dumps(shared_sme_string, cls=basyx.aas.adapter.json.AASToJsonEncoder)
|
|
346
380
|
sme_data = json.loads(sme_data_string)
|
|
347
381
|
|
|
348
382
|
result = client.post_submodel_element_submodel_repo(shared_sm.id, sme_data)
|
|
349
383
|
|
|
350
384
|
assert result is not None
|
|
351
|
-
assert result.get("idShort", "") ==
|
|
352
|
-
assert result.get("description", {})[0].get("text", "") ==
|
|
353
|
-
assert result.get("displayName", {})[0].get("text", "") ==
|
|
385
|
+
assert result.get("idShort", "") == shared_sme_string.id_short
|
|
386
|
+
assert result.get("description", {})[0].get("text", "") == shared_sme_string.description.get("en", "")
|
|
387
|
+
assert result.get("displayName", {})[0].get("text", "") == shared_sme_string.display_name.get("en", "")
|
|
388
|
+
assert result.get("value", "") == shared_sme_string.value
|
|
354
389
|
|
|
355
390
|
get_result = client.get_all_submodel_elements_submodel_repository(shared_sm.id)
|
|
356
391
|
|
|
357
392
|
assert len(get_result.get("result", [])) == 1
|
|
358
393
|
|
|
359
|
-
def
|
|
360
|
-
|
|
394
|
+
def test_016b_post_submodel_element_submodel_repo(client: AasHttpClient, shared_sm: model.Submodel, shared_sme_bool: model.Property):
|
|
395
|
+
sme_data_string = json.dumps(shared_sme_bool, cls=basyx.aas.adapter.json.AASToJsonEncoder)
|
|
396
|
+
sme_data = json.loads(sme_data_string)
|
|
397
|
+
|
|
398
|
+
result = client.post_submodel_element_submodel_repo(shared_sm.id, sme_data)
|
|
399
|
+
|
|
400
|
+
assert result is not None
|
|
401
|
+
assert result.get("idShort", "") == shared_sme_bool.id_short
|
|
402
|
+
assert result.get("description", {})[0].get("text", "") == shared_sme_bool.description.get("en", "")
|
|
403
|
+
assert result.get("displayName", {})[0].get("text", "") == shared_sme_bool.display_name.get("en", "")
|
|
404
|
+
assert json.loads(result.get("value", "").lower()) == shared_sme_bool.value
|
|
405
|
+
|
|
406
|
+
get_result = client.get_all_submodel_elements_submodel_repository(shared_sm.id)
|
|
407
|
+
|
|
408
|
+
assert len(get_result.get("result", [])) == 2
|
|
409
|
+
|
|
410
|
+
def test_016c_post_submodel_element_submodel_repo(client: AasHttpClient, shared_sm: model.Submodel, shared_sme_int: model.Property):
|
|
411
|
+
sme_data_string = json.dumps(shared_sme_int, cls=basyx.aas.adapter.json.AASToJsonEncoder)
|
|
412
|
+
sme_data = json.loads(sme_data_string)
|
|
413
|
+
|
|
414
|
+
result = client.post_submodel_element_submodel_repo(shared_sm.id, sme_data)
|
|
415
|
+
|
|
416
|
+
assert result is not None
|
|
417
|
+
assert result.get("idShort", "") == shared_sme_int.id_short
|
|
418
|
+
assert result.get("description", {})[0].get("text", "") == shared_sme_int.description.get("en", "")
|
|
419
|
+
assert result.get("displayName", {})[0].get("text", "") == shared_sme_int.display_name.get("en", "")
|
|
420
|
+
assert int(result.get("value", "")) == shared_sme_int.value
|
|
421
|
+
|
|
422
|
+
get_result = client.get_all_submodel_elements_submodel_repository(shared_sm.id)
|
|
423
|
+
|
|
424
|
+
assert len(get_result.get("result", [])) == 3
|
|
425
|
+
|
|
426
|
+
def test_016d_post_submodel_element_submodel_repo(client: AasHttpClient, shared_sm: model.Submodel, shared_sme_float: model.Property):
|
|
427
|
+
sme_data_string = json.dumps(shared_sme_float, cls=basyx.aas.adapter.json.AASToJsonEncoder)
|
|
428
|
+
sme_data = json.loads(sme_data_string)
|
|
429
|
+
|
|
430
|
+
result = client.post_submodel_element_submodel_repo(shared_sm.id, sme_data)
|
|
431
|
+
|
|
432
|
+
assert result is not None
|
|
433
|
+
assert result.get("idShort", "") == shared_sme_float.id_short
|
|
434
|
+
assert result.get("description", {})[0].get("text", "") == shared_sme_float.description.get("en", "")
|
|
435
|
+
assert result.get("displayName", {})[0].get("text", "") == shared_sme_float.display_name.get("en", "")
|
|
436
|
+
assert float(result.get("value", "")) == shared_sme_float.value
|
|
437
|
+
|
|
438
|
+
get_result = client.get_all_submodel_elements_submodel_repository(shared_sm.id)
|
|
439
|
+
|
|
440
|
+
assert len(get_result.get("result", [])) == 4
|
|
441
|
+
|
|
442
|
+
def test_017a_get_submodel_element_by_path_submodel_repo(client: AasHttpClient, shared_sm: model.Submodel, shared_sme_string: model.Property):
|
|
443
|
+
result = client.get_submodel_element_by_path_submodel_repo(shared_sm.id, shared_sme_string.id_short)
|
|
361
444
|
|
|
362
445
|
assert result is not None
|
|
363
|
-
assert result.get("idShort", "") ==
|
|
364
|
-
assert result.get("description", {})[0].get("text", "") ==
|
|
365
|
-
assert result.get("displayName", {})[0].get("text", "") ==
|
|
446
|
+
assert result.get("idShort", "") == shared_sme_string.id_short
|
|
447
|
+
assert result.get("description", {})[0].get("text", "") == shared_sme_string.description.get("en", "")
|
|
448
|
+
assert result.get("displayName", {})[0].get("text", "") == shared_sme_string.display_name.get("en", "")
|
|
449
|
+
assert result.get("value", "") == shared_sme_string.value
|
|
450
|
+
|
|
451
|
+
def test_017b_get_submodel_element_by_path_submodel_repo(client: AasHttpClient, shared_sm: model.Submodel, shared_sme_bool: model.Property):
|
|
452
|
+
result = client.get_submodel_element_by_path_submodel_repo(shared_sm.id, shared_sme_bool.id_short)
|
|
453
|
+
|
|
454
|
+
assert result is not None
|
|
455
|
+
assert result.get("idShort", "") == shared_sme_bool.id_short
|
|
456
|
+
assert result.get("description", {})[0].get("text", "") == shared_sme_bool.description.get("en", "")
|
|
457
|
+
assert result.get("displayName", {})[0].get("text", "") == shared_sme_bool.display_name.get("en", "")
|
|
458
|
+
assert json.loads(result.get("value", "").lower()) == shared_sme_bool.value
|
|
459
|
+
|
|
460
|
+
def test_017c_get_submodel_element_by_path_submodel_repo(client: AasHttpClient, shared_sm: model.Submodel, shared_sme_int: model.Property):
|
|
461
|
+
result = client.get_submodel_element_by_path_submodel_repo(shared_sm.id, shared_sme_int.id_short)
|
|
462
|
+
|
|
463
|
+
assert result is not None
|
|
464
|
+
assert result.get("idShort", "") == shared_sme_int.id_short
|
|
465
|
+
assert result.get("description", {})[0].get("text", "") == shared_sme_int.description.get("en", "")
|
|
466
|
+
assert result.get("displayName", {})[0].get("text", "") == shared_sme_int.display_name.get("en", "")
|
|
467
|
+
assert int(result.get("value", "")) == shared_sme_int.value
|
|
468
|
+
|
|
469
|
+
def test_017d_get_submodel_element_by_path_submodel_repo(client: AasHttpClient, shared_sm: model.Submodel, shared_sme_float: model.Property):
|
|
470
|
+
result = client.get_submodel_element_by_path_submodel_repo(shared_sm.id, shared_sme_float.id_short)
|
|
471
|
+
|
|
472
|
+
assert result is not None
|
|
473
|
+
assert result.get("idShort", "") == shared_sme_float.id_short
|
|
474
|
+
assert result.get("description", {})[0].get("text", "") == shared_sme_float.description.get("en", "")
|
|
475
|
+
assert result.get("displayName", {})[0].get("text", "") == shared_sme_float.display_name.get("en", "")
|
|
476
|
+
assert float(result.get("value", "")) == shared_sme_float.value
|
|
477
|
+
|
|
478
|
+
def test_018a_patch_submodel_element_by_path_value_only_submodel_repo(client: AasHttpClient, shared_sm: model.Submodel, shared_sme_string: model.Property):
|
|
479
|
+
new_value = "Patched String Value"
|
|
480
|
+
result = client.patch_submodel_element_by_path_value_only_submodel_repo(shared_sm.id, shared_sme_string.id_short, new_value)
|
|
481
|
+
|
|
482
|
+
parsed = urlparse(client.base_url)
|
|
483
|
+
if int(parsed.port) in PYTHON_SERVER_PORTS:
|
|
484
|
+
# NOTE: python server do not provide this endpoint
|
|
485
|
+
assert result is False
|
|
486
|
+
else:
|
|
487
|
+
assert result is True
|
|
488
|
+
|
|
489
|
+
get_result = client.get_submodel_element_by_path_submodel_repo(shared_sm.id, shared_sme_string.id_short)
|
|
490
|
+
|
|
491
|
+
assert get_result is not None
|
|
492
|
+
assert get_result.get("idShort", "") == shared_sme_string.id_short
|
|
493
|
+
assert get_result.get("value", "") == new_value
|
|
494
|
+
assert get_result.get("description", {})[0].get("text", "") == shared_sme_string.description.get("en", "")
|
|
495
|
+
assert get_result.get("displayName", {})[0].get("text", "") == shared_sme_string.display_name.get("en", "")
|
|
496
|
+
|
|
497
|
+
def test_018b_patch_submodel_element_by_path_value_only_submodel_repo(client: AasHttpClient, shared_sm: model.Submodel, shared_sme_bool: model.Property):
|
|
498
|
+
new_value = "false"
|
|
499
|
+
result = client.patch_submodel_element_by_path_value_only_submodel_repo(shared_sm.id, shared_sme_bool.id_short, new_value)
|
|
500
|
+
|
|
501
|
+
parsed = urlparse(client.base_url)
|
|
502
|
+
if int(parsed.port) in PYTHON_SERVER_PORTS:
|
|
503
|
+
# NOTE: python server do not provide this endpoint
|
|
504
|
+
assert result is False
|
|
505
|
+
else:
|
|
506
|
+
assert result is True
|
|
507
|
+
|
|
508
|
+
get_result = client.get_submodel_element_by_path_submodel_repo(shared_sm.id, shared_sme_bool.id_short)
|
|
509
|
+
|
|
510
|
+
assert get_result is not None
|
|
511
|
+
assert get_result.get("idShort", "") == shared_sme_bool.id_short
|
|
512
|
+
assert json.loads(get_result.get("value", "").lower()) == json.loads(new_value)
|
|
513
|
+
assert get_result.get("description", {})[0].get("text", "") == shared_sme_bool.description.get("en", "")
|
|
514
|
+
assert get_result.get("displayName", {})[0].get("text", "") == shared_sme_bool.display_name.get("en", "")
|
|
515
|
+
|
|
516
|
+
def test_018c_patch_submodel_element_by_path_value_only_submodel_repo(client: AasHttpClient, shared_sm: model.Submodel, shared_sme_int: model.Property):
|
|
517
|
+
new_value = "263"
|
|
518
|
+
result = client.patch_submodel_element_by_path_value_only_submodel_repo(shared_sm.id, shared_sme_int.id_short, new_value)
|
|
519
|
+
|
|
520
|
+
parsed = urlparse(client.base_url)
|
|
521
|
+
if int(parsed.port) in PYTHON_SERVER_PORTS:
|
|
522
|
+
# NOTE: python server do not provide this endpoint
|
|
523
|
+
assert result is False
|
|
524
|
+
else:
|
|
525
|
+
assert result is True
|
|
526
|
+
|
|
527
|
+
get_result = client.get_submodel_element_by_path_submodel_repo(shared_sm.id, shared_sme_int.id_short)
|
|
528
|
+
|
|
529
|
+
assert get_result is not None
|
|
530
|
+
assert get_result.get("idShort", "") == shared_sme_int.id_short
|
|
531
|
+
assert int(get_result.get("value", "")) == int(new_value)
|
|
532
|
+
assert get_result.get("description", {})[0].get("text", "") == shared_sme_int.description.get("en", "")
|
|
533
|
+
assert get_result.get("displayName", {})[0].get("text", "") == shared_sme_int.display_name.get("en", "")
|
|
534
|
+
|
|
535
|
+
def test_018d_patch_submodel_element_by_path_value_only_submodel_repo(client: AasHttpClient, shared_sm: model.Submodel, shared_sme_float: model.Property):
|
|
536
|
+
new_value = "262.1"
|
|
537
|
+
result = client.patch_submodel_element_by_path_value_only_submodel_repo(shared_sm.id, shared_sme_float.id_short, new_value)
|
|
538
|
+
|
|
539
|
+
parsed = urlparse(client.base_url)
|
|
540
|
+
if int(parsed.port) in PYTHON_SERVER_PORTS:
|
|
541
|
+
# NOTE: python server do not provide this endpoint
|
|
542
|
+
assert result is False
|
|
543
|
+
else:
|
|
544
|
+
assert result is True
|
|
545
|
+
|
|
546
|
+
get_result = client.get_submodel_element_by_path_submodel_repo(shared_sm.id, shared_sme_float.id_short)
|
|
547
|
+
|
|
548
|
+
assert get_result is not None
|
|
549
|
+
assert get_result.get("idShort", "") == shared_sme_float.id_short
|
|
550
|
+
assert float(get_result.get("value", "")) == float(new_value)
|
|
551
|
+
assert get_result.get("description", {})[0].get("text", "") == shared_sme_float.description.get("en", "")
|
|
552
|
+
assert get_result.get("displayName", {})[0].get("text", "") == shared_sme_float.display_name.get("en", "")
|
|
366
553
|
|
|
367
554
|
def test_098_delete_asset_administration_shell_by_id(client: AasHttpClient, shared_aas: model.AssetAdministrationShell):
|
|
368
555
|
result = client.delete_asset_administration_shell_by_id(shared_aas.id)
|
|
369
556
|
|
|
370
|
-
assert result
|
|
557
|
+
assert result is True
|
|
371
558
|
|
|
372
559
|
get_result = client.get_all_asset_administration_shells()
|
|
373
560
|
assert get_result is not None
|
|
@@ -377,7 +564,7 @@ def test_098_delete_asset_administration_shell_by_id(client: AasHttpClient, shar
|
|
|
377
564
|
def test_099_delete_submodel_by_id(client: AasHttpClient, shared_sm: model.Submodel):
|
|
378
565
|
result = client.delete_submodel_by_id(shared_sm.id)
|
|
379
566
|
|
|
380
|
-
assert result
|
|
567
|
+
assert result is True
|
|
381
568
|
|
|
382
569
|
get_result = client.get_all_submodels()
|
|
383
570
|
assert get_result is not None
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import pytest
|
|
2
2
|
from pathlib import Path
|
|
3
|
-
from aas_http_client.wrapper.sdk_wrapper import create_wrapper_by_config, SdkWrapper
|
|
3
|
+
from aas_http_client.wrapper.sdk_wrapper import create_wrapper_by_config, SdkWrapper, create_wrapper_by_dict, create_wrapper_by_url
|
|
4
4
|
from basyx.aas import model
|
|
5
5
|
import aas_http_client.utilities.model_builder as model_builder
|
|
6
6
|
from urllib.parse import urlparse
|
|
7
|
+
import json
|
|
7
8
|
|
|
8
9
|
JAVA_SERVER_PORTS = [8075]
|
|
9
10
|
PYTHON_SERVER_PORTS = [8080, 80]
|
|
@@ -15,6 +16,10 @@ CONFIG_FILES = [
|
|
|
15
16
|
"./tests/server_configs/test_python_server_config.json"
|
|
16
17
|
]
|
|
17
18
|
|
|
19
|
+
# CONFIG_FILES = [
|
|
20
|
+
# "./tests/server_configs/test_dotnet_server_config_local.json",
|
|
21
|
+
# ]
|
|
22
|
+
|
|
18
23
|
@pytest.fixture(params=CONFIG_FILES, scope="module")
|
|
19
24
|
def wrapper(request) -> SdkWrapper:
|
|
20
25
|
try:
|
|
@@ -34,9 +39,24 @@ def wrapper(request) -> SdkWrapper:
|
|
|
34
39
|
return wrapper
|
|
35
40
|
|
|
36
41
|
@pytest.fixture(scope="module")
|
|
37
|
-
def
|
|
42
|
+
def shared_sme_string() -> model.Property:
|
|
43
|
+
# create a Submodel
|
|
44
|
+
return model_builder.create_base_submodel_element_Property("sme_property_string", model.datatypes.String, "Sample String Value")
|
|
45
|
+
|
|
46
|
+
@pytest.fixture(scope="module")
|
|
47
|
+
def shared_sme_bool() -> model.Property:
|
|
48
|
+
# create a Submodel
|
|
49
|
+
return model_builder.create_base_submodel_element_Property("sme_property_bool", model.datatypes.Boolean, True)
|
|
50
|
+
|
|
51
|
+
@pytest.fixture(scope="module")
|
|
52
|
+
def shared_sme_int() -> model.Property:
|
|
53
|
+
# create a Submodel
|
|
54
|
+
return model_builder.create_base_submodel_element_Property("sme_property_int", model.datatypes.Integer, 262)
|
|
55
|
+
|
|
56
|
+
@pytest.fixture(scope="module")
|
|
57
|
+
def shared_sme_float() -> model.Property:
|
|
38
58
|
# create a Submodel
|
|
39
|
-
return model_builder.create_base_submodel_element_Property("
|
|
59
|
+
return model_builder.create_base_submodel_element_Property("sme_property_float", model.datatypes.Float, 262.3)
|
|
40
60
|
|
|
41
61
|
@pytest.fixture(scope="module")
|
|
42
62
|
def shared_sm() -> model.Submodel:
|
|
@@ -55,6 +75,21 @@ def shared_aas(shared_sm: model.Submodel) -> model.AssetAdministrationShell:
|
|
|
55
75
|
|
|
56
76
|
return aas
|
|
57
77
|
|
|
78
|
+
def test_000a_create_wrapper_by_url(wrapper: SdkWrapper):
|
|
79
|
+
base_url: str = wrapper.base_url
|
|
80
|
+
new_client: SdkWrapper = create_wrapper_by_url(base_url=base_url)
|
|
81
|
+
assert new_client is not None
|
|
82
|
+
|
|
83
|
+
def test_000b_create_wrapper_by_dict(wrapper: SdkWrapper):
|
|
84
|
+
base_url: str = wrapper.base_url
|
|
85
|
+
|
|
86
|
+
config_dict: dict = {
|
|
87
|
+
"base_url": base_url
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
new_client: SdkWrapper = create_wrapper_by_dict(configuration=config_dict)
|
|
91
|
+
assert new_client is not None
|
|
92
|
+
|
|
58
93
|
def test_001_connect(wrapper: SdkWrapper):
|
|
59
94
|
assert wrapper is not None
|
|
60
95
|
|
|
@@ -292,42 +327,217 @@ def test_015_get_all_submodel_elements_submodel_repository(wrapper: SdkWrapper,
|
|
|
292
327
|
assert submodel_elements is not None
|
|
293
328
|
assert len(submodel_elements) == 0
|
|
294
329
|
|
|
295
|
-
def
|
|
296
|
-
submodel_element = wrapper.post_submodel_element_submodel_repo(shared_sm.id,
|
|
330
|
+
def test_016a_post_submodel_element_submodel_repo(wrapper: SdkWrapper, shared_sm: model.Submodel, shared_sme_string: model.Property):
|
|
331
|
+
submodel_element = wrapper.post_submodel_element_submodel_repo(shared_sm.id, shared_sme_string)
|
|
297
332
|
|
|
298
333
|
assert submodel_element is not None
|
|
299
334
|
|
|
300
|
-
parsed = urlparse(wrapper.base_url)
|
|
301
|
-
if int(parsed.port) in DOTNET_SERVER_PORTS:
|
|
302
|
-
# NOTE: dotNet server provides a wrong representation of submodel elements
|
|
303
|
-
return
|
|
304
|
-
|
|
305
335
|
assert isinstance(submodel_element, model.Property)
|
|
336
|
+
property: model.Property = submodel_element
|
|
337
|
+
assert property.value == shared_sme_string.value
|
|
306
338
|
|
|
307
|
-
assert submodel_element.id_short ==
|
|
308
|
-
assert submodel_element.description.get("en", "") ==
|
|
309
|
-
assert submodel_element.display_name.get("en", "") ==
|
|
339
|
+
assert submodel_element.id_short == shared_sme_string.id_short
|
|
340
|
+
assert submodel_element.description.get("en", "") == shared_sme_string.description.get("en", "")
|
|
341
|
+
assert submodel_element.display_name.get("en", "") == shared_sme_string.display_name.get("en", "")
|
|
342
|
+
assert submodel_element.value == shared_sme_string.value
|
|
310
343
|
|
|
311
344
|
submodel_elements = wrapper.get_all_submodel_elements_submodel_repository(shared_sm.id)
|
|
312
345
|
|
|
313
346
|
assert submodel_elements is not None
|
|
314
347
|
assert len(submodel_elements) == 1
|
|
315
348
|
|
|
316
|
-
def
|
|
317
|
-
submodel_element = wrapper.
|
|
349
|
+
def test_016b_post_submodel_element_submodel_repo(wrapper: SdkWrapper, shared_sm: model.Submodel, shared_sme_bool: model.Property):
|
|
350
|
+
submodel_element = wrapper.post_submodel_element_submodel_repo(shared_sm.id, shared_sme_bool)
|
|
318
351
|
|
|
319
352
|
assert submodel_element is not None
|
|
320
353
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
354
|
+
assert isinstance(submodel_element, model.Property)
|
|
355
|
+
property: model.Property = submodel_element
|
|
356
|
+
assert property.value == shared_sme_bool.value
|
|
357
|
+
|
|
358
|
+
assert submodel_element.id_short == shared_sme_bool.id_short
|
|
359
|
+
assert submodel_element.description.get("en", "") == shared_sme_bool.description.get("en", "")
|
|
360
|
+
assert submodel_element.display_name.get("en", "") == shared_sme_bool.display_name.get("en", "")
|
|
361
|
+
assert submodel_element.value == shared_sme_bool.value
|
|
362
|
+
|
|
363
|
+
submodel_elements = wrapper.get_all_submodel_elements_submodel_repository(shared_sm.id)
|
|
364
|
+
|
|
365
|
+
assert submodel_elements is not None
|
|
366
|
+
assert len(submodel_elements) == 2
|
|
367
|
+
|
|
368
|
+
def test_016c_post_submodel_element_submodel_repo(wrapper: SdkWrapper, shared_sm: model.Submodel, shared_sme_int: model.Property):
|
|
369
|
+
submodel_element = wrapper.post_submodel_element_submodel_repo(shared_sm.id, shared_sme_int)
|
|
370
|
+
|
|
371
|
+
assert submodel_element is not None
|
|
372
|
+
|
|
373
|
+
assert isinstance(submodel_element, model.Property)
|
|
374
|
+
property: model.Property = submodel_element
|
|
375
|
+
assert property.value == shared_sme_int.value
|
|
376
|
+
|
|
377
|
+
assert submodel_element.id_short == shared_sme_int.id_short
|
|
378
|
+
assert submodel_element.description.get("en", "") == shared_sme_int.description.get("en", "")
|
|
379
|
+
assert submodel_element.display_name.get("en", "") == shared_sme_int.display_name.get("en", "")
|
|
380
|
+
assert submodel_element.value == shared_sme_int.value
|
|
381
|
+
|
|
382
|
+
submodel_elements = wrapper.get_all_submodel_elements_submodel_repository(shared_sm.id)
|
|
383
|
+
|
|
384
|
+
assert submodel_elements is not None
|
|
385
|
+
assert len(submodel_elements) == 3
|
|
386
|
+
|
|
387
|
+
def test_016d_post_submodel_element_submodel_repo(wrapper: SdkWrapper, shared_sm: model.Submodel, shared_sme_float: model.Property):
|
|
388
|
+
submodel_element = wrapper.post_submodel_element_submodel_repo(shared_sm.id, shared_sme_float)
|
|
389
|
+
|
|
390
|
+
assert submodel_element is not None
|
|
391
|
+
|
|
392
|
+
assert isinstance(submodel_element, model.Property)
|
|
393
|
+
property: model.Property = submodel_element
|
|
394
|
+
assert property.value == shared_sme_float.value
|
|
395
|
+
|
|
396
|
+
assert submodel_element.id_short == shared_sme_float.id_short
|
|
397
|
+
assert submodel_element.description.get("en", "") == shared_sme_float.description.get("en", "")
|
|
398
|
+
assert submodel_element.display_name.get("en", "") == shared_sme_float.display_name.get("en", "")
|
|
399
|
+
assert submodel_element.value == shared_sme_float.value
|
|
400
|
+
|
|
401
|
+
submodel_elements = wrapper.get_all_submodel_elements_submodel_repository(shared_sm.id)
|
|
402
|
+
|
|
403
|
+
assert submodel_elements is not None
|
|
404
|
+
assert len(submodel_elements) == 4
|
|
405
|
+
|
|
406
|
+
def test_017a_get_submodel_element_by_path_submodel_repo(wrapper: SdkWrapper, shared_sm: model.Submodel, shared_sme_string: model.Property):
|
|
407
|
+
submodel_element = wrapper.get_submodel_element_by_path_submodel_repo(shared_sm.id, shared_sme_string.id_short)
|
|
408
|
+
|
|
409
|
+
assert submodel_element is not None
|
|
410
|
+
|
|
411
|
+
assert isinstance(submodel_element, model.Property)
|
|
412
|
+
|
|
413
|
+
assert submodel_element.id_short == shared_sme_string.id_short
|
|
414
|
+
assert submodel_element.description.get("en", "") == shared_sme_string.description.get("en", "")
|
|
415
|
+
assert submodel_element.display_name.get("en", "") == shared_sme_string.display_name.get("en", "")
|
|
416
|
+
assert submodel_element.value == shared_sme_string.value
|
|
417
|
+
|
|
418
|
+
def test_017b_get_submodel_element_by_path_submodel_repo(wrapper: SdkWrapper, shared_sm: model.Submodel, shared_sme_bool: model.Property):
|
|
419
|
+
submodel_element = wrapper.get_submodel_element_by_path_submodel_repo(shared_sm.id, shared_sme_bool.id_short)
|
|
420
|
+
|
|
421
|
+
assert submodel_element is not None
|
|
422
|
+
|
|
423
|
+
assert isinstance(submodel_element, model.Property)
|
|
424
|
+
|
|
425
|
+
assert submodel_element.id_short == shared_sme_bool.id_short
|
|
426
|
+
assert submodel_element.description.get("en", "") == shared_sme_bool.description.get("en", "")
|
|
427
|
+
assert submodel_element.display_name.get("en", "") == shared_sme_bool.display_name.get("en", "")
|
|
428
|
+
assert submodel_element.value == shared_sme_bool.value
|
|
429
|
+
|
|
430
|
+
def test_017c_get_submodel_element_by_path_submodel_repo(wrapper: SdkWrapper, shared_sm: model.Submodel, shared_sme_int: model.Property):
|
|
431
|
+
submodel_element = wrapper.get_submodel_element_by_path_submodel_repo(shared_sm.id, shared_sme_int.id_short)
|
|
432
|
+
|
|
433
|
+
assert submodel_element is not None
|
|
434
|
+
|
|
435
|
+
assert isinstance(submodel_element, model.Property)
|
|
436
|
+
|
|
437
|
+
assert submodel_element.id_short == shared_sme_int.id_short
|
|
438
|
+
assert submodel_element.description.get("en", "") == shared_sme_int.description.get("en", "")
|
|
439
|
+
assert submodel_element.display_name.get("en", "") == shared_sme_int.display_name.get("en", "")
|
|
440
|
+
assert submodel_element.value == shared_sme_int.value
|
|
441
|
+
|
|
442
|
+
def test_017d_get_submodel_element_by_path_submodel_repo(wrapper: SdkWrapper, shared_sm: model.Submodel, shared_sme_float: model.Property):
|
|
443
|
+
submodel_element = wrapper.get_submodel_element_by_path_submodel_repo(shared_sm.id, shared_sme_float.id_short)
|
|
444
|
+
|
|
445
|
+
assert submodel_element is not None
|
|
325
446
|
|
|
326
447
|
assert isinstance(submodel_element, model.Property)
|
|
327
448
|
|
|
328
|
-
assert submodel_element.id_short ==
|
|
329
|
-
assert submodel_element.description.get("en", "") ==
|
|
330
|
-
assert submodel_element.display_name.get("en", "") ==
|
|
449
|
+
assert submodel_element.id_short == shared_sme_float.id_short
|
|
450
|
+
assert submodel_element.description.get("en", "") == shared_sme_float.description.get("en", "")
|
|
451
|
+
assert submodel_element.display_name.get("en", "") == shared_sme_float.display_name.get("en", "")
|
|
452
|
+
assert submodel_element.value == shared_sme_float.value
|
|
453
|
+
|
|
454
|
+
def test_018a_patch_submodel_element_by_path_value_only_submodel_repo(wrapper: SdkWrapper, shared_sm: model.Submodel, shared_sme_string: model.Property):
|
|
455
|
+
new_value = "Patched String Value"
|
|
456
|
+
result = wrapper.patch_submodel_element_by_path_value_only_submodel_repo(shared_sm.id, shared_sme_string.id_short, new_value)
|
|
457
|
+
|
|
458
|
+
parsed = urlparse(wrapper.base_url)
|
|
459
|
+
if int(parsed.port) in PYTHON_SERVER_PORTS:
|
|
460
|
+
# NOTE: python server do not provide this endpoint
|
|
461
|
+
assert result is False
|
|
462
|
+
else:
|
|
463
|
+
assert result is True
|
|
464
|
+
|
|
465
|
+
submodel_element = wrapper.get_submodel_element_by_path_submodel_repo(shared_sm.id, shared_sme_string.id_short)
|
|
466
|
+
|
|
467
|
+
assert submodel_element is not None
|
|
468
|
+
assert submodel_element.id_short == shared_sme_string.id_short
|
|
469
|
+
assert submodel_element.description.get("en", "") == shared_sme_string.description.get("en", "")
|
|
470
|
+
assert submodel_element.display_name.get("en", "") == shared_sme_string.display_name.get("en", "")
|
|
471
|
+
|
|
472
|
+
assert isinstance(submodel_element, model.Property)
|
|
473
|
+
property: model.Property = submodel_element
|
|
474
|
+
assert property.value == new_value
|
|
475
|
+
|
|
476
|
+
def test_018b_patch_submodel_element_by_path_value_only_submodel_repo(wrapper: SdkWrapper, shared_sm: model.Submodel, shared_sme_bool: model.Property):
|
|
477
|
+
new_value = "false"
|
|
478
|
+
result = wrapper.patch_submodel_element_by_path_value_only_submodel_repo(shared_sm.id, shared_sme_bool.id_short, new_value)
|
|
479
|
+
|
|
480
|
+
parsed = urlparse(wrapper.base_url)
|
|
481
|
+
if int(parsed.port) in PYTHON_SERVER_PORTS:
|
|
482
|
+
# NOTE: python server do not provide this endpoint
|
|
483
|
+
assert result is False
|
|
484
|
+
else:
|
|
485
|
+
assert result is True
|
|
486
|
+
|
|
487
|
+
submodel_element = wrapper.get_submodel_element_by_path_submodel_repo(shared_sm.id, shared_sme_bool.id_short)
|
|
488
|
+
|
|
489
|
+
assert submodel_element is not None
|
|
490
|
+
assert submodel_element.id_short == shared_sme_bool.id_short
|
|
491
|
+
assert submodel_element.description.get("en", "") == shared_sme_bool.description.get("en", "")
|
|
492
|
+
assert submodel_element.display_name.get("en", "") == shared_sme_bool.display_name.get("en", "")
|
|
493
|
+
|
|
494
|
+
assert isinstance(submodel_element, model.Property)
|
|
495
|
+
property: model.Property = submodel_element
|
|
496
|
+
assert property.value == json.loads(new_value)
|
|
497
|
+
|
|
498
|
+
def test_018c_patch_submodel_element_by_path_value_only_submodel_repo(wrapper: SdkWrapper, shared_sm: model.Submodel, shared_sme_int: model.Property):
|
|
499
|
+
new_value = "263"
|
|
500
|
+
result = wrapper.patch_submodel_element_by_path_value_only_submodel_repo(shared_sm.id, shared_sme_int.id_short, new_value)
|
|
501
|
+
|
|
502
|
+
parsed = urlparse(wrapper.base_url)
|
|
503
|
+
if int(parsed.port) in PYTHON_SERVER_PORTS:
|
|
504
|
+
# NOTE: python server do not provide this endpoint
|
|
505
|
+
assert result is False
|
|
506
|
+
else:
|
|
507
|
+
assert result is True
|
|
508
|
+
|
|
509
|
+
submodel_element = wrapper.get_submodel_element_by_path_submodel_repo(shared_sm.id, shared_sme_int.id_short)
|
|
510
|
+
|
|
511
|
+
assert submodel_element is not None
|
|
512
|
+
assert submodel_element.id_short == shared_sme_int.id_short
|
|
513
|
+
assert submodel_element.description.get("en", "") == shared_sme_int.description.get("en", "")
|
|
514
|
+
assert submodel_element.display_name.get("en", "") == shared_sme_int.display_name.get("en", "")
|
|
515
|
+
|
|
516
|
+
assert isinstance(submodel_element, model.Property)
|
|
517
|
+
property: model.Property = submodel_element
|
|
518
|
+
assert property.value == int(new_value)
|
|
519
|
+
|
|
520
|
+
def test_018d_patch_submodel_element_by_path_value_only_submodel_repo(wrapper: SdkWrapper, shared_sm: model.Submodel, shared_sme_float: model.Property):
|
|
521
|
+
new_value = "262.1"
|
|
522
|
+
result = wrapper.patch_submodel_element_by_path_value_only_submodel_repo(shared_sm.id, shared_sme_float.id_short, new_value)
|
|
523
|
+
|
|
524
|
+
parsed = urlparse(wrapper.base_url)
|
|
525
|
+
if int(parsed.port) in PYTHON_SERVER_PORTS:
|
|
526
|
+
# NOTE: python server do not provide this endpoint
|
|
527
|
+
assert result is False
|
|
528
|
+
else:
|
|
529
|
+
assert result is True
|
|
530
|
+
|
|
531
|
+
submodel_element = wrapper.get_submodel_element_by_path_submodel_repo(shared_sm.id, shared_sme_float.id_short)
|
|
532
|
+
|
|
533
|
+
assert submodel_element is not None
|
|
534
|
+
assert submodel_element.id_short == shared_sme_float.id_short
|
|
535
|
+
assert submodel_element.description.get("en", "") == shared_sme_float.description.get("en", "")
|
|
536
|
+
assert submodel_element.display_name.get("en", "") == shared_sme_float.display_name.get("en", "")
|
|
537
|
+
|
|
538
|
+
assert isinstance(submodel_element, model.Property)
|
|
539
|
+
property: model.Property = submodel_element
|
|
540
|
+
assert property.value == float(new_value)
|
|
331
541
|
|
|
332
542
|
def test_098_delete_asset_administration_shell_by_id(wrapper: SdkWrapper, shared_aas: model.AssetAdministrationShell):
|
|
333
543
|
result = wrapper.delete_asset_administration_shell_by_id(shared_aas.id)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{aas_http_client-0.3.1 → aas_http_client-0.3.3}/aas_http_client.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|