aas-http-client 0.2.0__tar.gz → 0.2.2__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.

Potentially problematic release.


This version of aas-http-client might be problematic. Click here for more details.

Files changed (18) hide show
  1. {aas_http_client-0.2.0 → aas_http_client-0.2.2}/PKG-INFO +16 -2
  2. {aas_http_client-0.2.0 → aas_http_client-0.2.2}/README.md +14 -0
  3. {aas_http_client-0.2.0 → aas_http_client-0.2.2}/aas_http_client/client.py +10 -5
  4. {aas_http_client-0.2.0 → aas_http_client-0.2.2}/aas_http_client/demo/demo_process.py +15 -7
  5. {aas_http_client-0.2.0 → aas_http_client-0.2.2}/aas_http_client/wrapper/sdk_wrapper.py +57 -47
  6. {aas_http_client-0.2.0 → aas_http_client-0.2.2}/aas_http_client.egg-info/PKG-INFO +16 -2
  7. {aas_http_client-0.2.0 → aas_http_client-0.2.2}/pyproject.toml +2 -2
  8. {aas_http_client-0.2.0 → aas_http_client-0.2.2}/LICENSE +0 -0
  9. {aas_http_client-0.2.0 → aas_http_client-0.2.2}/aas_http_client/__init__.py +0 -0
  10. {aas_http_client-0.2.0 → aas_http_client-0.2.2}/aas_http_client/core/encoder.py +0 -0
  11. {aas_http_client-0.2.0 → aas_http_client-0.2.2}/aas_http_client/core/version_check.py +0 -0
  12. {aas_http_client-0.2.0 → aas_http_client-0.2.2}/aas_http_client/demo/logging_handler.py +0 -0
  13. {aas_http_client-0.2.0 → aas_http_client-0.2.2}/aas_http_client/utilities/__init__.py +0 -0
  14. {aas_http_client-0.2.0 → aas_http_client-0.2.2}/aas_http_client/utilities/model_builder.py +0 -0
  15. {aas_http_client-0.2.0 → aas_http_client-0.2.2}/aas_http_client.egg-info/SOURCES.txt +0 -0
  16. {aas_http_client-0.2.0 → aas_http_client-0.2.2}/aas_http_client.egg-info/dependency_links.txt +0 -0
  17. {aas_http_client-0.2.0 → aas_http_client-0.2.2}/aas_http_client.egg-info/top_level.txt +0 -0
  18. {aas_http_client-0.2.0 → aas_http_client-0.2.2}/setup.cfg +0 -0
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aas-http-client
3
- Version: 0.2.0
4
- Summary: Generic HTTP client for communicating with various types of AAS servers
3
+ Version: 0.2.2
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
7
7
 
@@ -155,6 +155,8 @@ For a detailed introduction, please read [Getting Started](docs/getting_started.
155
155
  pip install aas-http-client
156
156
  ````
157
157
 
158
+ ### Client
159
+
158
160
  ```python
159
161
  from aas_http_client import create_client_by_url
160
162
 
@@ -164,3 +166,15 @@ client = create_client_by_url(
164
166
 
165
167
  print(client.get_shells())
166
168
  ```
169
+
170
+ ### SDK Wrapper
171
+
172
+ ```python
173
+ from aas_http_client.wrapper.sdk_wrapper import create_wrapper_by_config
174
+
175
+ wrapper = create_wrapper_by_config(
176
+ base_url="http://myaasserver:5043/"
177
+ )
178
+
179
+ print(wrapper.get_shells())
180
+ ```
@@ -43,6 +43,8 @@ For a detailed introduction, please read [Getting Started](docs/getting_started.
43
43
  pip install aas-http-client
44
44
  ````
45
45
 
46
+ ### Client
47
+
46
48
  ```python
47
49
  from aas_http_client import create_client_by_url
48
50
 
@@ -51,4 +53,16 @@ client = create_client_by_url(
51
53
  )
52
54
 
53
55
  print(client.get_shells())
56
+ ```
57
+
58
+ ### SDK Wrapper
59
+
60
+ ```python
61
+ from aas_http_client.wrapper.sdk_wrapper import create_wrapper_by_config
62
+
63
+ wrapper = create_wrapper_by_config(
64
+ base_url="http://myaasserver:5043/"
65
+ )
66
+
67
+ print(wrapper.get_shells())
54
68
  ```
@@ -20,6 +20,7 @@ STATUS_CODE_200 = 200
20
20
  STATUS_CODE_201 = 201
21
21
  STATUS_CODE_202 = 202
22
22
  STATUS_CODE_204 = 204
23
+ STATUS_CODE_404 = 404
23
24
  HEADERS = {"Content-Type": "application/json"}
24
25
 
25
26
 
@@ -54,6 +55,9 @@ def log_response_errors(response: Response):
54
55
  result_error_messages.append(str(message))
55
56
  elif "error" in response_content_dict:
56
57
  result_error_messages.append(response_content_dict.get("error", ""))
58
+
59
+ if len(result_error_messages) == 0 and response.text:
60
+ result_error_messages.append(response.text)
57
61
 
58
62
  except json.JSONDecodeError:
59
63
  result_error_messages.append(response.content)
@@ -484,13 +488,14 @@ def create_client_by_config(config_file: Path, password: str = "") -> AasHttpCli
484
488
  :param password: password for the BaSyx server interface client, defaults to ""_
485
489
  :return: An instance of HttpClient initialized with the provided parameters.
486
490
  """
487
- logger.info(f"Create BaSyx server interface client from config file '{config_file}'")
491
+ config_file = config_file.resolve()
492
+ logger.info(f"Create AAS HTTP client from Configuration file '{config_file}'")
488
493
  if not config_file.exists():
489
494
  config_string = "{}"
490
- logger.warning(f"Server config file '{config_file}' not found. Using default config.")
495
+ logger.warning(f"Configuration file '{config_file}' not found. Using default configuration.")
491
496
  else:
492
497
  config_string = config_file.read_text(encoding="utf-8")
493
- logger.debug(f"Server config file '{config_file}' found.")
498
+ logger.debug(f"Configuration file '{config_file}' found.")
494
499
 
495
500
  return _create_client(config_string, password)
496
501
 
@@ -529,12 +534,12 @@ def _connect_to_api(client: AasHttpClient) -> bool:
529
534
  try:
530
535
  root = client.get_root()
531
536
  if root:
532
- logger.info(f"Connected to REST API at '{client.base_url}' successfully.")
537
+ logger.info(f"Connected to server API at '{client.base_url}' successfully.")
533
538
  return True
534
539
  except requests.exceptions.ConnectionError:
535
540
  pass
536
541
  if time.time() - start_time > client.connection_time_out:
537
- raise TimeoutError(f"Connection to REST API timed out after {client.connection_time_out} seconds.")
542
+ raise TimeoutError(f"Connection to server API timed out after {client.connection_time_out} seconds.")
538
543
 
539
544
  counter += 1
540
545
  logger.warning(f"Retrying connection (attempt: {counter})")
@@ -16,15 +16,23 @@ def start():
16
16
  aas_2 = _create_shell()
17
17
 
18
18
  client = _create_client()
19
- sdk_wrapper = _create_sdk_wrapper()
19
+ java_sdk_wrapper = _create_sdk_wrapper(Path("./aas_http_client/demo/java_server_config.json"))
20
+ dotnet_sdk_wrapper = _create_sdk_wrapper(Path("./aas_http_client/demo/dotnet_server_config.json"))
20
21
 
21
- exist_shells = sdk_wrapper.get_shells()
22
+ java_sdk_wrapper.get_shells_by_id(aas_1.id)
23
+ dotnet_sdk_wrapper.get_shells_by_id(aas_1.id)
24
+
25
+ java_sdk_wrapper.get_submodels_by_id(aas_1.id)
26
+ dotnet_sdk_wrapper.get_submodels_by_id(aas_1.id)
27
+
28
+ exist_shells = java_sdk_wrapper.get_shells()
29
+ exist_shells = dotnet_sdk_wrapper.get_shells()
22
30
 
23
31
  for shell in exist_shells:
24
32
  logger.warning(f"Delete shell '{shell.id}'")
25
- sdk_wrapper.delete_shells_by_id(shell.id)
33
+ java_sdk_wrapper.delete_shells_by_id(shell.id)
26
34
 
27
- sdk_wrapper.post_shells(aas_1)
35
+ java_sdk_wrapper.post_shells(aas_1)
28
36
 
29
37
 
30
38
  aas_dict_string = json.dumps(aas_2, cls=basyx.aas.adapter.json.AASToJsonEncoder)
@@ -53,7 +61,7 @@ def _create_client() -> AasHttpClient:
53
61
  """Create client for java servers."""
54
62
 
55
63
  try:
56
- file = Path("./demo/server_config.json")
64
+ file = Path("./aas_http_client/demo/java_server_config.json")
57
65
  client = create_client_by_config(file, password="")
58
66
  except Exception as e:
59
67
  logger.error(f"Failed to create client for {file}: {e}")
@@ -61,11 +69,11 @@ def _create_client() -> AasHttpClient:
61
69
 
62
70
  return client
63
71
 
64
- def _create_sdk_wrapper() -> SdkWrapper:
72
+ def _create_sdk_wrapper(config: Path) -> SdkWrapper:
65
73
  """Create client for java servers."""
66
74
 
67
75
  try:
68
- file = Path("./demo/server_config.json")
76
+ file = config
69
77
  client = create_wrapper_by_config(file, password="")
70
78
  except Exception as e:
71
79
  logger.error(f"Failed to create client for {file}: {e}")
@@ -3,6 +3,7 @@
3
3
  import json
4
4
  import logging
5
5
  from pathlib import Path
6
+ from typing import Any
6
7
 
7
8
  import basyx.aas.adapter.json
8
9
 
@@ -20,9 +21,7 @@ class SdkWrapper():
20
21
  :param aas: Asset Administration Shell to post
21
22
  :return: Response data as a dictionary or None if an error occurred
22
23
  """
23
- aas_data_string = json.dumps(aas, cls=basyx.aas.adapter.json.AASToJsonEncoder)
24
- aas_data = json.loads(aas_data_string)
25
-
24
+ aas_data = _to_dict(aas)
26
25
  return self._client.post_shells(aas_data)
27
26
 
28
27
  def put_shells(self, identifier: str, aas: AssetAdministrationShell) -> bool:
@@ -32,9 +31,7 @@ class SdkWrapper():
32
31
  :param aas: Asset Administration Shell data to update
33
32
  :return: True if the update was successful, False otherwise
34
33
  """
35
- aas_data_string = json.dumps(aas, cls=basyx.aas.adapter.json.AASToJsonEncoder)
36
- aas_data = json.loads(aas_data_string)
37
-
34
+ aas_data = _to_dict(aas)
38
35
  return self._client.put_shells(identifier, aas_data)
39
36
 
40
37
  def put_shells_submodels_by_id(self, aas_id: str, submodel_id: str, submodel: Submodel) -> bool:
@@ -44,9 +41,7 @@ class SdkWrapper():
44
41
  :param submodel: Submodel data to update
45
42
  :return: True if the update was successful, False otherwise
46
43
  """
47
- sm_data_string = json.dumps(submodel, cls=basyx.aas.adapter.json.AASToJsonEncoder)
48
- sm_data = json.loads(sm_data_string)
49
-
44
+ sm_data = _to_dict(submodel)
50
45
  return self._client.put_shells_submodels_by_id(aas_id, submodel_id, sm_data)
51
46
 
52
47
  def get_shells(self) -> list[AssetAdministrationShell] | None:
@@ -57,24 +52,24 @@ class SdkWrapper():
57
52
  content: dict = self._client.get_shells()
58
53
 
59
54
  if not content:
60
- logger.warning("No AAS found in the REST API.")
61
- return []
55
+ return None
62
56
 
63
57
  results: list = content.get("result", [])
64
58
  if not results:
65
- logger.warning("No AAS found in the REST API results.")
59
+ logger.warning("No shells found on server.")
66
60
  return []
67
61
 
68
62
  aas_list: list[AssetAdministrationShell] = []
69
63
 
70
64
  for result in results:
71
65
  if not isinstance(result, dict):
72
- logger.error(f"Invalid AAS data: {result}")
66
+ logger.error(f"Invalid shell data: {result}")
73
67
  return None
74
68
 
75
- aas_dict_string = json.dumps(result)
76
- aas = json.loads(aas_dict_string, cls=basyx.aas.adapter.json.AASFromJsonDecoder)
77
- aas_list.append(aas)
69
+ aas = _to_object(result)
70
+
71
+ if aas:
72
+ aas_list.append(aas)
78
73
 
79
74
  return aas_list
80
75
 
@@ -85,8 +80,12 @@ class SdkWrapper():
85
80
  :return: AAS object or None if an error occurred
86
81
  """
87
82
  content: dict = self._client.get_shells_by_id(aas_id)
88
- aas_dict_string = json.dumps(content)
89
- return json.loads(aas_dict_string, cls=basyx.aas.adapter.json.AASFromJsonDecoder)
83
+
84
+ if not content:
85
+ logger.warning(f"No shell found with ID '{aas_id}' on server.")
86
+ return None
87
+
88
+ return _to_object(content)
90
89
 
91
90
  def get_shells_reference_by_id(self, aas_id: str) -> Reference | None:
92
91
  #workaround because serialization not working
@@ -104,8 +103,7 @@ class SdkWrapper():
104
103
  :return: Submodel object or None if an error occurred
105
104
  """
106
105
  content: dict = self._client.get_shells_submodels_by_id(aas_id, submodel_id)
107
- sm_dict_string = json.dumps(content)
108
- return json.loads(sm_dict_string, cls=basyx.aas.adapter.json.AASFromJsonDecoder)
106
+ return _to_object(content)
109
107
 
110
108
  def delete_shells_by_id(self, aas_id: str) -> bool:
111
109
  """Get an Asset Administration Shell (AAS) by its ID from the REST API.
@@ -121,9 +119,7 @@ class SdkWrapper():
121
119
  :param submodel: submodel data as a dictionary
122
120
  :return: Response data as a dictionary or None if an error occurred
123
121
  """
124
- sm_data_string = json.dumps(submodel, cls=basyx.aas.adapter.json.AASToJsonEncoder)
125
- sm_data = json.loads(sm_data_string)
126
-
122
+ sm_data = _to_dict(submodel)
127
123
  return self._client.post_submodels(sm_data)
128
124
 
129
125
  def put_submodels_by_id(self, identifier: str, submodel: Submodel) -> bool:
@@ -133,9 +129,7 @@ class SdkWrapper():
133
129
  :param submodel: Submodel data to update
134
130
  :return: True if the update was successful, False otherwise
135
131
  """
136
- sm_data_string = json.dumps(submodel, cls=basyx.aas.adapter.json.AASToJsonEncoder)
137
- sm_data = json.loads(sm_data_string)
138
-
132
+ sm_data = _to_dict(submodel)
139
133
  return self._client.put_submodels_by_id(identifier, sm_data)
140
134
 
141
135
  def get_submodels(self) -> list[Submodel] | None:
@@ -146,12 +140,11 @@ class SdkWrapper():
146
140
  content: list = self._client.get_submodels()
147
141
 
148
142
  if not content:
149
- logger.warning("No submodels found in the REST API.")
150
143
  return []
151
144
 
152
145
  results: list = content.get("result", [])
153
146
  if not results:
154
- logger.warning("No submodels found in the REST API results.")
147
+ logger.warning("No submodels found on server.")
155
148
  return []
156
149
 
157
150
  submodels: list[Submodel] = []
@@ -161,9 +154,10 @@ class SdkWrapper():
161
154
  logger.error(f"Invalid submodel data: {result}")
162
155
  return None
163
156
 
164
- sm_dict_string = json.dumps(result)
165
- submodel = json.loads(sm_dict_string, cls=basyx.aas.adapter.json.AASFromJsonDecoder)
166
- submodels.append(submodel)
157
+ submodel = _to_object(result)
158
+
159
+ if submodel:
160
+ submodels.append(submodel)
167
161
 
168
162
  return submodels
169
163
 
@@ -176,21 +170,14 @@ class SdkWrapper():
176
170
  content = self._client.get_submodels_by_id(submodel_id)
177
171
 
178
172
  if not content:
179
- logger.warning(f"No submodel found with ID '{submodel_id}' in the REST API.")
180
- return None
181
-
182
- if not isinstance(content, dict):
183
- logger.error(f"Invalid submodel data: {content}")
173
+ logger.warning(f"No submodel found with ID '{submodel_id}' on server.")
184
174
  return None
185
175
 
186
- sm_dict_string = json.dumps(content)
187
- return json.loads(sm_dict_string, cls=basyx.aas.adapter.json.AASFromJsonDecoder)
176
+ return _to_object(content)
188
177
 
189
178
  def patch_submodel_by_id(self, submodel_id: str, submodel: Submodel):
190
- sm_dict_string = json.dumps(submodel, cls=basyx.aas.adapter.json.AASToJsonEncoder)
191
- sm_dict = json.loads(sm_dict_string)
192
-
193
- return self._client.patch_submodel_by_id(submodel_id, sm_dict)
179
+ sm_data = _to_dict(submodel)
180
+ return self._client.patch_submodel_by_id(submodel_id, sm_data)
194
181
 
195
182
  def delete_submodels_by_id(self, submodel_id: str) -> bool:
196
183
  """Delete a submodel by its ID from the REST API.
@@ -200,6 +187,24 @@ class SdkWrapper():
200
187
  """
201
188
  return self._client.delete_submodels_by_id(submodel_id)
202
189
 
190
+ def _to_object(content: dict) -> Any | None:
191
+ try:
192
+ dict_string = json.dumps(content)
193
+ return json.loads(dict_string, cls=basyx.aas.adapter.json.AASFromJsonDecoder)
194
+ except Exception as e:
195
+ logger.error(f"Decoding error: {e}")
196
+ logger.error(f"In JSON: {content}")
197
+ return None
198
+
199
+ def _to_dict(object: Any) -> dict | None:
200
+ try:
201
+ data_string = json.dumps(object, cls=basyx.aas.adapter.json.AASToJsonEncoder)
202
+ return json.loads(data_string)
203
+ except Exception as e:
204
+ logger.error(f"Encoding error: {e}")
205
+ logger.error(f"In object: {object}")
206
+ return None
207
+
203
208
  def create_wrapper_by_url(
204
209
  base_url: str,
205
210
  username: str = "",
@@ -234,7 +239,12 @@ def create_wrapper_by_url(
234
239
  config_string = json.dumps(config_dict, indent=4)
235
240
 
236
241
  wrapper = SdkWrapper()
237
- wrapper._client = _create_client(config_string, password)
242
+ client = _create_client(config_string, password)
243
+
244
+ if not client:
245
+ return None
246
+
247
+ wrapper._client = client
238
248
  return wrapper
239
249
 
240
250
 
@@ -246,13 +256,13 @@ def create_wrapper_by_config(config_file: Path, password: str = "") -> AasHttpCl
246
256
  :param password: password for the BaSyx server interface client, defaults to ""_
247
257
  :return: An instance of HttpClient initialized with the provided parameters.
248
258
  """
249
- logger.info(f"Create BaSyx server interface client from config file '{config_file}'")
259
+ logger.info(f"Create BaSyx Python SDK wrapper from configuration file '{config_file}'")
250
260
  if not config_file.exists():
251
261
  config_string = "{}"
252
- logger.warning(f"Server config file '{config_file}' not found. Using default config.")
262
+ logger.warning(f"Configuration file '{config_file}' not found. Using default config.")
253
263
  else:
254
264
  config_string = config_file.read_text(encoding="utf-8")
255
- logger.debug(f"Server config file '{config_file}' found.")
265
+ logger.debug(f"Configuration file '{config_file}' found.")
256
266
 
257
267
  wrapper = SdkWrapper()
258
268
  client = _create_client(config_string, password)
@@ -260,5 +270,5 @@ def create_wrapper_by_config(config_file: Path, password: str = "") -> AasHttpCl
260
270
  if not client:
261
271
  return None
262
272
 
263
- wrapper._client = _create_client(config_string, password)
273
+ wrapper._client = client
264
274
  return wrapper
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aas-http-client
3
- Version: 0.2.0
4
- Summary: Generic HTTP client for communicating with various types of AAS servers
3
+ Version: 0.2.2
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
7
7
 
@@ -155,6 +155,8 @@ For a detailed introduction, please read [Getting Started](docs/getting_started.
155
155
  pip install aas-http-client
156
156
  ````
157
157
 
158
+ ### Client
159
+
158
160
  ```python
159
161
  from aas_http_client import create_client_by_url
160
162
 
@@ -164,3 +166,15 @@ client = create_client_by_url(
164
166
 
165
167
  print(client.get_shells())
166
168
  ```
169
+
170
+ ### SDK Wrapper
171
+
172
+ ```python
173
+ from aas_http_client.wrapper.sdk_wrapper import create_wrapper_by_config
174
+
175
+ wrapper = create_wrapper_by_config(
176
+ base_url="http://myaasserver:5043/"
177
+ )
178
+
179
+ print(wrapper.get_shells())
180
+ ```
@@ -4,8 +4,8 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "aas-http-client"
7
- version = "0.2.00"
8
- description = "Generic HTTP client for communicating with various types of AAS servers"
7
+ version = "0.2.2"
8
+ description = "Generic python HTTP client for communication with various types of AAS servers"
9
9
  readme = "README.md"
10
10
  license = { file = "LICENSE" }
11
11
  authors = [
File without changes