aas-http-client 0.1.4__py3-none-any.whl → 0.1.6__py3-none-any.whl
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.
- aas_http_client/__init__.py +9 -3
- aas_http_client/client.py +63 -159
- aas_http_client/demo/demo_process.py +74 -0
- aas_http_client/demo/logging_handler.py +177 -0
- aas_http_client/utilities/__init__.py +0 -0
- aas_http_client/utilities/model_builder.py +120 -0
- aas_http_client/wrapper/python_sdk_wrapper_tmp.py +641 -0
- aas_http_client/wrapper/sdk_wrapper.py +272 -0
- {aas_http_client-0.1.4.dist-info → aas_http_client-0.1.6.dist-info}/METADATA +5 -4
- aas_http_client-0.1.6.dist-info/RECORD +15 -0
- aas_http_client-0.1.4.dist-info/RECORD +0 -9
- {aas_http_client-0.1.4.dist-info → aas_http_client-0.1.6.dist-info}/WHEEL +0 -0
- {aas_http_client-0.1.4.dist-info → aas_http_client-0.1.6.dist-info}/licenses/LICENSE +0 -0
- {aas_http_client-0.1.4.dist-info → aas_http_client-0.1.6.dist-info}/top_level.txt +0 -0
aas_http_client/__init__.py
CHANGED
|
@@ -4,13 +4,19 @@ import importlib.metadata
|
|
|
4
4
|
__copyright__ = f"Copyright (C) {datetime.now().year} :em engineering methods AG. All rights reserved."
|
|
5
5
|
__author__ = "Daniel Klein"
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
try:
|
|
8
|
+
__version__ = importlib.metadata.version(__name__)
|
|
9
|
+
except importlib.metadata.PackageNotFoundError:
|
|
10
|
+
__version__ = "0.0.0-dev"
|
|
11
|
+
|
|
8
12
|
__project__ = "aas-http-client"
|
|
9
13
|
__package__ = "aas-http-client"
|
|
10
14
|
|
|
11
15
|
from aas_http_client.core.version_check import check_for_update
|
|
12
|
-
from aas_http_client.client import create_client_by_config, create_client_by_url,
|
|
16
|
+
from aas_http_client.client import create_client_by_config, create_client_by_url, AasHttpClient
|
|
17
|
+
from aas_http_client.utilities import model_builder
|
|
18
|
+
from aas_http_client.wrapper.sdk_wrapper import create_wrapper_by_config, create_wrapper_by_url, SdkWrapper
|
|
13
19
|
|
|
14
20
|
check_for_update()
|
|
15
21
|
|
|
16
|
-
__all__ = ["create_client_by_config", "create_client_by_url", "
|
|
22
|
+
__all__ = ["create_client_by_config", "create_client_by_url", "AasHttpClient", "model_builder", "create_wrapper_by_config", "create_wrapper_by_url", "SdkWrapper"]
|
aas_http_client/client.py
CHANGED
|
@@ -1,16 +1,14 @@
|
|
|
1
|
-
"""
|
|
2
|
-
|
|
1
|
+
"""Client for HTTP API communication with AAS server."""
|
|
3
2
|
import json
|
|
4
3
|
import logging
|
|
5
|
-
import re
|
|
6
4
|
import time
|
|
7
5
|
from pathlib import Path
|
|
8
6
|
|
|
9
7
|
import basyx.aas.adapter.json
|
|
10
8
|
import basyx.aas.adapter.json.json_serialization as js
|
|
11
9
|
import requests
|
|
12
|
-
from basyx.aas.model import
|
|
13
|
-
from aas_http_client.core.encoder import decode_base_64
|
|
10
|
+
from basyx.aas.model import Reference, Submodel
|
|
11
|
+
from aas_http_client.core.encoder import decode_base_64
|
|
14
12
|
from pydantic import BaseModel, PrivateAttr, ValidationError
|
|
15
13
|
from requests import Session
|
|
16
14
|
from requests.auth import HTTPBasicAuth
|
|
@@ -65,10 +63,11 @@ def log_response_errors(response: Response):
|
|
|
65
63
|
logger.error(result_error_message)
|
|
66
64
|
|
|
67
65
|
|
|
68
|
-
class
|
|
69
|
-
"""Represents a
|
|
66
|
+
class AasHttpClient(BaseModel):
|
|
67
|
+
"""Represents a AasHttpClient to communicate with a REST API."""
|
|
70
68
|
|
|
71
|
-
base_url: str = "http://
|
|
69
|
+
base_url: str = "http://javaaasserver:5060/"
|
|
70
|
+
api_base_path: str = ""
|
|
72
71
|
username: str | None = None
|
|
73
72
|
_password: str | None = PrivateAttr(default=None)
|
|
74
73
|
https_proxy: str | None = None
|
|
@@ -77,10 +76,9 @@ class AasxServerInterface(BaseModel):
|
|
|
77
76
|
connection_time_out: int = 100
|
|
78
77
|
ssl_verify: bool = True
|
|
79
78
|
_session: Session = PrivateAttr(default=None)
|
|
80
|
-
namespace: str | None = None
|
|
81
79
|
|
|
82
80
|
def initialize(self, password: str):
|
|
83
|
-
"""Initialize the
|
|
81
|
+
"""Initialize the AasHttpClient with the given URL, username and password.
|
|
84
82
|
|
|
85
83
|
:param password: password
|
|
86
84
|
"""
|
|
@@ -98,21 +96,6 @@ class AasxServerInterface(BaseModel):
|
|
|
98
96
|
if self.http_proxy:
|
|
99
97
|
self._session.proxies.update({"http": self.http_proxy})
|
|
100
98
|
|
|
101
|
-
if not self.namespace:
|
|
102
|
-
self.namespace = re.sub(r":\d+", "", self.base_url)
|
|
103
|
-
|
|
104
|
-
def _get_namespace(self) -> str:
|
|
105
|
-
"""Get the address of the REST API.
|
|
106
|
-
|
|
107
|
-
:return: address as a string
|
|
108
|
-
"""
|
|
109
|
-
match = re.search(r"^https?://([^:/]+)", self.base_url)
|
|
110
|
-
|
|
111
|
-
if match:
|
|
112
|
-
return match.group(1)
|
|
113
|
-
|
|
114
|
-
raise ValueError(f"Invalid URL format: {self.base_url}")
|
|
115
|
-
|
|
116
99
|
def get_root(self) -> dict | None:
|
|
117
100
|
"""Get the root of the REST API.
|
|
118
101
|
|
|
@@ -132,22 +115,20 @@ class AasxServerInterface(BaseModel):
|
|
|
132
115
|
logger.error(f"Error call REST API: {e}")
|
|
133
116
|
return None
|
|
134
117
|
|
|
135
|
-
|
|
118
|
+
content = response.content.decode("utf-8")
|
|
119
|
+
return json.loads(content)
|
|
136
120
|
|
|
137
|
-
def post_shells(self,
|
|
121
|
+
def post_shells(self, aas_data: dict) -> dict | None:
|
|
138
122
|
"""Post an Asset Administration Shell (AAS) to the REST API.
|
|
139
123
|
|
|
140
|
-
:param
|
|
124
|
+
:param aas_data: Json data of the Asset Administration Shell to post
|
|
141
125
|
:return: Response data as a dictionary or None if an error occurred
|
|
142
126
|
"""
|
|
143
|
-
aas_dict_string = json.dumps(aas, cls=basyx.aas.adapter.json.AASToJsonEncoder)
|
|
144
|
-
aas_dict = json.loads(aas_dict_string)
|
|
145
|
-
|
|
146
127
|
url = f"{self.base_url}/shells"
|
|
147
128
|
logger.debug(f"Call REST API url '{url}'")
|
|
148
129
|
|
|
149
130
|
try:
|
|
150
|
-
response = self._session.post(url, headers=HEADERS, json=
|
|
131
|
+
response = self._session.post(url, headers=HEADERS, json=aas_data, timeout=self.time_out)
|
|
151
132
|
logger.debug(f"Call REST API url '{response.url}'")
|
|
152
133
|
|
|
153
134
|
if response.status_code not in (STATUS_CODE_201, STATUS_CODE_202):
|
|
@@ -158,24 +139,21 @@ class AasxServerInterface(BaseModel):
|
|
|
158
139
|
logger.error(f"Error call REST API: {e}")
|
|
159
140
|
return None
|
|
160
141
|
|
|
161
|
-
content =
|
|
162
|
-
return
|
|
142
|
+
content = response.content.decode("utf-8")
|
|
143
|
+
return json.loads(content)
|
|
163
144
|
|
|
164
|
-
def put_shells(self, identifier: str,
|
|
145
|
+
def put_shells(self, identifier: str, aas_data: dict) -> bool:
|
|
165
146
|
"""Update an Asset Administration Shell (AAS) by its ID in the REST API.
|
|
166
147
|
|
|
167
148
|
:param identifier: Identifier of the AAS to update
|
|
168
|
-
:param
|
|
149
|
+
:param aas_data: Json data of the Asset Administration Shell data to update
|
|
169
150
|
:return: True if the update was successful, False otherwise
|
|
170
151
|
"""
|
|
171
|
-
aas_dict_string = json.dumps(aas, cls=basyx.aas.adapter.json.AASToJsonEncoder)
|
|
172
|
-
aas_dict = json.loads(aas_dict_string)
|
|
173
|
-
|
|
174
152
|
decoded_identifier: str = decode_base_64(identifier)
|
|
175
153
|
url = f"{self.base_url}/shells/{decoded_identifier}"
|
|
176
154
|
|
|
177
155
|
try:
|
|
178
|
-
response = self._session.put(url, headers=HEADERS, json=
|
|
156
|
+
response = self._session.put(url, headers=HEADERS, json=aas_data, timeout=self.time_out)
|
|
179
157
|
logger.debug(f"Call REST API url '{response.url}'")
|
|
180
158
|
|
|
181
159
|
if response.status_code is not STATUS_CODE_204:
|
|
@@ -188,22 +166,19 @@ class AasxServerInterface(BaseModel):
|
|
|
188
166
|
|
|
189
167
|
return True
|
|
190
168
|
|
|
191
|
-
def
|
|
169
|
+
def put_shells_submodels_by_id(self, aas_id: str, submodel_id: str, submodel_data: dict) -> bool:
|
|
192
170
|
"""Update a submodel by its ID for a specific Asset Administration Shell (AAS).
|
|
193
171
|
|
|
194
172
|
:param aas_id: ID of the AAS to update the submodel for
|
|
195
|
-
:param
|
|
173
|
+
:param submodel_data: Json data to the Submodel to update
|
|
196
174
|
:return: True if the update was successful, False otherwise
|
|
197
175
|
"""
|
|
198
|
-
sm_dict_string = json.dumps(submodel, cls=basyx.aas.adapter.json.AASToJsonEncoder)
|
|
199
|
-
sm_dict = json.loads(sm_dict_string)
|
|
200
|
-
|
|
201
176
|
decoded_aas_id: str = decode_base_64(aas_id)
|
|
202
177
|
decoded_submodel_id: str = decode_base_64(submodel_id)
|
|
203
178
|
url = f"{self.base_url}/shells/{decoded_aas_id}/submodels/{decoded_submodel_id}"
|
|
204
179
|
|
|
205
180
|
try:
|
|
206
|
-
response = self._session.put(url, headers=HEADERS, json=
|
|
181
|
+
response = self._session.put(url, headers=HEADERS, json=submodel_data, timeout=self.time_out)
|
|
207
182
|
logger.debug(f"Call REST API url '{response.url}'")
|
|
208
183
|
|
|
209
184
|
if response.status_code != STATUS_CODE_204:
|
|
@@ -216,10 +191,10 @@ class AasxServerInterface(BaseModel):
|
|
|
216
191
|
|
|
217
192
|
return True
|
|
218
193
|
|
|
219
|
-
def get_shells(self) -> list[
|
|
194
|
+
def get_shells(self) -> list[dict] | None:
|
|
220
195
|
"""Get all Asset Administration Shells (AAS) from the REST API.
|
|
221
196
|
|
|
222
|
-
:return:
|
|
197
|
+
:return: List of paginated Asset Administration Shells data or None if an error occurred
|
|
223
198
|
"""
|
|
224
199
|
url = f"{self.base_url}/shells"
|
|
225
200
|
|
|
@@ -235,35 +210,14 @@ class AasxServerInterface(BaseModel):
|
|
|
235
210
|
logger.error(f"Error call REST API: {e}")
|
|
236
211
|
return None
|
|
237
212
|
|
|
238
|
-
content
|
|
239
|
-
|
|
240
|
-
if not content:
|
|
241
|
-
logger.warning("No AAS found in the REST API.")
|
|
242
|
-
return []
|
|
243
|
-
|
|
244
|
-
results: list = content.get("result", [])
|
|
245
|
-
if not results:
|
|
246
|
-
logger.warning("No AAS found in the REST API results.")
|
|
247
|
-
return []
|
|
248
|
-
|
|
249
|
-
aas_list: list[AssetAdministrationShell] = []
|
|
213
|
+
content = response.content.decode("utf-8")
|
|
214
|
+
return json.loads(content)
|
|
250
215
|
|
|
251
|
-
|
|
252
|
-
if not isinstance(result, dict):
|
|
253
|
-
logger.error(f"Invalid AAS data: {result}")
|
|
254
|
-
return None
|
|
255
|
-
|
|
256
|
-
aas_dict_string = json.dumps(result)
|
|
257
|
-
aas = json.loads(aas_dict_string, cls=basyx.aas.adapter.json.AASFromJsonDecoder)
|
|
258
|
-
aas_list.append(aas)
|
|
259
|
-
|
|
260
|
-
return aas_list
|
|
261
|
-
|
|
262
|
-
def get_shells_by_id(self, aas_id: str) -> AssetAdministrationShell | None:
|
|
216
|
+
def get_shells_by_id(self, aas_id: str) -> dict | None:
|
|
263
217
|
"""Get an Asset Administration Shell (AAS) by its ID from the REST API.
|
|
264
218
|
|
|
265
219
|
:param aas_id: ID of the AAS to retrieve
|
|
266
|
-
:return:
|
|
220
|
+
:return: Asset Administration Shells data or None if an error occurred
|
|
267
221
|
"""
|
|
268
222
|
decoded_aas_id: str = decode_base_64(aas_id)
|
|
269
223
|
url = f"{self.base_url}/shells/{decoded_aas_id}"
|
|
@@ -280,8 +234,9 @@ class AasxServerInterface(BaseModel):
|
|
|
280
234
|
logger.error(f"Error call REST API: {e}")
|
|
281
235
|
return None
|
|
282
236
|
|
|
283
|
-
|
|
284
|
-
return json.loads(
|
|
237
|
+
content = response.content.decode("utf-8")
|
|
238
|
+
return json.loads(content)
|
|
239
|
+
|
|
285
240
|
|
|
286
241
|
def get_shells_reference_by_id(self, aas_id: str) -> Reference | None:
|
|
287
242
|
decoded_aas_id: str = decode_base_64(aas_id)
|
|
@@ -302,7 +257,7 @@ class AasxServerInterface(BaseModel):
|
|
|
302
257
|
ref_dict_string = response.content.decode("utf-8")
|
|
303
258
|
return json.loads(ref_dict_string, cls=basyx.aas.adapter.json.AASFromJsonDecoder)
|
|
304
259
|
|
|
305
|
-
def
|
|
260
|
+
def get_shells_submodels_by_id(self, aas_id: str, submodel_id: str) -> Submodel | None:
|
|
306
261
|
"""Get a submodel by its ID for a specific Asset Administration Shell (AAS).
|
|
307
262
|
|
|
308
263
|
:param aas_id: ID of the AAS to retrieve the submodel from
|
|
@@ -313,6 +268,7 @@ class AasxServerInterface(BaseModel):
|
|
|
313
268
|
decoded_submodel_id: str = decode_base_64(submodel_id)
|
|
314
269
|
|
|
315
270
|
url = f"{self.base_url}/shells/{decoded_aas_id}/submodels/{decoded_submodel_id}"
|
|
271
|
+
#/shells/{aasIdentifier}/submodels/{submodelIdentifier}
|
|
316
272
|
|
|
317
273
|
try:
|
|
318
274
|
response = self._session.get(url, headers=HEADERS, timeout=self.time_out)
|
|
@@ -326,8 +282,8 @@ class AasxServerInterface(BaseModel):
|
|
|
326
282
|
logger.error(f"Error call REST API: {e}")
|
|
327
283
|
return None
|
|
328
284
|
|
|
329
|
-
|
|
330
|
-
return json.loads(
|
|
285
|
+
content = response.content.decode("utf-8")
|
|
286
|
+
return json.loads(content)
|
|
331
287
|
|
|
332
288
|
def delete_shells_by_id(self, aas_id: str) -> bool:
|
|
333
289
|
"""Get an Asset Administration Shell (AAS) by its ID from the REST API.
|
|
@@ -352,19 +308,16 @@ class AasxServerInterface(BaseModel):
|
|
|
352
308
|
|
|
353
309
|
return True
|
|
354
310
|
|
|
355
|
-
def post_submodels(self,
|
|
311
|
+
def post_submodels(self, submodel_data: dict) -> dict:
|
|
356
312
|
"""Post a submodel to the REST API.
|
|
357
313
|
|
|
358
|
-
:param
|
|
314
|
+
:param submodel_data: Json data of the Submodel to post
|
|
359
315
|
:return: Response data as a dictionary or None if an error occurred
|
|
360
316
|
"""
|
|
361
|
-
sm_dict_string = json.dumps(submodel, cls=basyx.aas.adapter.json.AASToJsonEncoder)
|
|
362
|
-
sm_dict = json.loads(sm_dict_string)
|
|
363
|
-
|
|
364
317
|
url = f"{self.base_url}/submodels"
|
|
365
318
|
|
|
366
319
|
try:
|
|
367
|
-
response = self._session.post(url, headers=HEADERS, json=
|
|
320
|
+
response = self._session.post(url, headers=HEADERS, json=submodel_data, timeout=self.time_out)
|
|
368
321
|
logger.debug(f"Call REST API url '{response.url}'")
|
|
369
322
|
|
|
370
323
|
if response.status_code not in (STATUS_CODE_201, STATUS_CODE_202):
|
|
@@ -375,23 +328,21 @@ class AasxServerInterface(BaseModel):
|
|
|
375
328
|
logger.error(f"Error call REST API: {e}")
|
|
376
329
|
return False
|
|
377
330
|
|
|
378
|
-
|
|
331
|
+
content = response.content.decode("utf-8")
|
|
332
|
+
return json.loads(content)
|
|
379
333
|
|
|
380
|
-
def
|
|
334
|
+
def put_submodels_by_id(self, identifier: str, submodel_data: dict) -> bool:
|
|
381
335
|
"""Update a submodel by its ID in the REST API.
|
|
382
336
|
|
|
383
337
|
:param identifier: Identifier of the submodel to update
|
|
384
|
-
:param
|
|
338
|
+
:param submodel_data: Json data of the Submodel to update
|
|
385
339
|
:return: True if the update was successful, False otherwise
|
|
386
340
|
"""
|
|
387
|
-
sm_dict_string = json.dumps(submodel, cls=basyx.aas.adapter.json.AASToJsonEncoder)
|
|
388
|
-
sm_dict = json.loads(sm_dict_string)
|
|
389
|
-
|
|
390
341
|
decoded_identifier: str = decode_base_64(identifier)
|
|
391
342
|
url = f"{self.base_url}/submodels/{decoded_identifier}"
|
|
392
343
|
|
|
393
344
|
try:
|
|
394
|
-
response = self._session.put(url, headers=HEADERS, json=
|
|
345
|
+
response = self._session.put(url, headers=HEADERS, json=submodel_data, timeout=self.time_out)
|
|
395
346
|
logger.debug(f"Call REST API url '{response.url}'")
|
|
396
347
|
|
|
397
348
|
if response.status_code != STATUS_CODE_204:
|
|
@@ -404,31 +355,7 @@ class AasxServerInterface(BaseModel):
|
|
|
404
355
|
|
|
405
356
|
return True
|
|
406
357
|
|
|
407
|
-
def
|
|
408
|
-
"""Get a submodel by its ID from the REST API.
|
|
409
|
-
|
|
410
|
-
:param submodel_id: ID of the submodel to retrieve
|
|
411
|
-
:return: Submodel object or None if an error occurred
|
|
412
|
-
"""
|
|
413
|
-
decoded_submodel_id: str = decode_base_64(submodel_id)
|
|
414
|
-
url = f"{self.base_url}/submodels/{decoded_submodel_id}"
|
|
415
|
-
|
|
416
|
-
try:
|
|
417
|
-
response = self._session.get(url, headers=HEADERS, timeout=self.time_out)
|
|
418
|
-
logger.debug(f"Call REST API url '{response.url}'")
|
|
419
|
-
|
|
420
|
-
if response.status_code != STATUS_CODE_200:
|
|
421
|
-
log_response_errors(response)
|
|
422
|
-
return None
|
|
423
|
-
|
|
424
|
-
except requests.exceptions.RequestException as e:
|
|
425
|
-
logger.error(f"Error call REST API: {e}")
|
|
426
|
-
return None
|
|
427
|
-
|
|
428
|
-
sm_dict_string = response.content.decode("utf-8")
|
|
429
|
-
return json.loads(sm_dict_string, cls=basyx.aas.adapter.json.AASFromJsonDecoder)
|
|
430
|
-
|
|
431
|
-
def get_submodels(self) -> list[Submodel] | None:
|
|
358
|
+
def get_submodels(self) -> list[dict] | None:
|
|
432
359
|
"""Get all submodels from the REST API.
|
|
433
360
|
|
|
434
361
|
:return: Submodel objects or None if an error occurred
|
|
@@ -447,31 +374,10 @@ class AasxServerInterface(BaseModel):
|
|
|
447
374
|
logger.error(f"Error call REST API: {e}")
|
|
448
375
|
return None
|
|
449
376
|
|
|
450
|
-
content
|
|
451
|
-
|
|
452
|
-
if not content:
|
|
453
|
-
logger.warning("No submodels found in the REST API.")
|
|
454
|
-
return []
|
|
455
|
-
|
|
456
|
-
results: list = content.get("result", [])
|
|
457
|
-
if not results:
|
|
458
|
-
logger.warning("No submodels found in the REST API results.")
|
|
459
|
-
return []
|
|
377
|
+
content = response.content.decode("utf-8")
|
|
378
|
+
return json.loads(content)
|
|
460
379
|
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
for result in results:
|
|
464
|
-
if not isinstance(result, dict):
|
|
465
|
-
logger.error(f"Invalid submodel data: {result}")
|
|
466
|
-
return None
|
|
467
|
-
|
|
468
|
-
sm_dict_string = json.dumps(result)
|
|
469
|
-
submodel = json.loads(sm_dict_string, cls=basyx.aas.adapter.json.AASFromJsonDecoder)
|
|
470
|
-
submodels.append(submodel)
|
|
471
|
-
|
|
472
|
-
return submodels
|
|
473
|
-
|
|
474
|
-
def get_submodels_by_id(self, submodel_id: str) -> Submodel | None:
|
|
380
|
+
def get_submodels_by_id(self, submodel_id: str) -> dict | None:
|
|
475
381
|
"""Get a submodel by its ID from the REST API.
|
|
476
382
|
|
|
477
383
|
:param submodel_id: ID of the submodel to retrieve
|
|
@@ -492,18 +398,15 @@ class AasxServerInterface(BaseModel):
|
|
|
492
398
|
logger.error(f"Error call REST API: {e}")
|
|
493
399
|
return None
|
|
494
400
|
|
|
495
|
-
|
|
496
|
-
return json.loads(
|
|
497
|
-
|
|
498
|
-
def patch_submodel_by_id(self, submodel_id: str, submodel: Submodel):
|
|
499
|
-
sm_dict_string = json.dumps(submodel, cls=basyx.aas.adapter.json.AASToJsonEncoder)
|
|
500
|
-
sm_dict = json.loads(sm_dict_string)
|
|
401
|
+
content = response.content.decode("utf-8")
|
|
402
|
+
return json.loads(content)
|
|
501
403
|
|
|
404
|
+
def patch_submodel_by_id(self, submodel_id: str, submodel_data: dict):
|
|
502
405
|
decoded_submodel_id: str = decode_base_64(submodel_id)
|
|
503
406
|
url = f"{self.base_url}/submodels/{decoded_submodel_id}"
|
|
504
407
|
|
|
505
408
|
try:
|
|
506
|
-
response = self._session.patch(url, headers=HEADERS, json=
|
|
409
|
+
response = self._session.patch(url, headers=HEADERS, json=submodel_data, timeout=self.time_out)
|
|
507
410
|
logger.debug(f"Call REST API url '{response.url}'")
|
|
508
411
|
|
|
509
412
|
if response.status_code != STATUS_CODE_204:
|
|
@@ -542,6 +445,7 @@ class AasxServerInterface(BaseModel):
|
|
|
542
445
|
|
|
543
446
|
def create_client_by_url(
|
|
544
447
|
base_url: str,
|
|
448
|
+
api_base_path: str = "",
|
|
545
449
|
username: str = "",
|
|
546
450
|
password: str = "",
|
|
547
451
|
http_proxy: str = "",
|
|
@@ -549,9 +453,8 @@ def create_client_by_url(
|
|
|
549
453
|
time_out: int = 200,
|
|
550
454
|
connection_time_out: int = 60,
|
|
551
455
|
ssl_verify: str = True, # noqa: FBT002
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
"""Create a BaSyx server interface client from the given parameters.
|
|
456
|
+
) -> AasHttpClient | None:
|
|
457
|
+
"""Create a AAS HTTP client from the given parameters.
|
|
555
458
|
|
|
556
459
|
:param base_url: base URL of the BaSyx server, e.g. "http://basyx_python_server:80/"_
|
|
557
460
|
:param username: username for the BaSyx server interface client, defaults to ""_
|
|
@@ -561,28 +464,28 @@ def create_client_by_url(
|
|
|
561
464
|
:param time_out: timeout for the API calls, defaults to 200
|
|
562
465
|
:param connection_time_out: timeout for the connection to the API, defaults to 60
|
|
563
466
|
:param ssl_verify: whether to verify SSL certificates, defaults to True
|
|
564
|
-
:return: An instance of
|
|
467
|
+
:return: An instance of AasHttpClient initialized with the provided parameters.
|
|
565
468
|
"""
|
|
566
469
|
logger.info(f"Create BaSyx server interface client from URL '{base_url}'")
|
|
567
470
|
config_dict: dict[str, str] = {}
|
|
568
471
|
config_dict["base_url"] = base_url
|
|
472
|
+
config_dict["api_base_path"] = api_base_path
|
|
569
473
|
config_dict["username"] = username
|
|
570
474
|
config_dict["http_proxy"] = http_proxy
|
|
571
475
|
config_dict["https_proxy"] = https_proxy
|
|
572
476
|
config_dict["time_out"] = time_out
|
|
573
477
|
config_dict["connection_time_out"] = connection_time_out
|
|
574
478
|
config_dict["ssl_verify"] = ssl_verify
|
|
575
|
-
config_dict["namespace"] = namespace
|
|
576
479
|
config_string = json.dumps(config_dict, indent=4)
|
|
577
480
|
return _create_client(config_string, password)
|
|
578
481
|
|
|
579
482
|
|
|
580
|
-
def create_client_by_config(config_file: Path, password: str = "") ->
|
|
581
|
-
"""Create a
|
|
483
|
+
def create_client_by_config(config_file: Path, password: str = "") -> AasHttpClient | None:
|
|
484
|
+
"""Create a AAS HTTP client from the given parameters.
|
|
582
485
|
|
|
583
486
|
:param config_file: Path to the configuration file containing the BaSyx server connection settings.
|
|
584
487
|
:param password: password for the BaSyx server interface client, defaults to ""_
|
|
585
|
-
:return: An instance of
|
|
488
|
+
:return: An instance of HttpClient initialized with the provided parameters.
|
|
586
489
|
"""
|
|
587
490
|
logger.info(f"Create BaSyx server interface client from config file '{config_file}'")
|
|
588
491
|
if not config_file.exists():
|
|
@@ -595,15 +498,16 @@ def create_client_by_config(config_file: Path, password: str = "") -> AasxServer
|
|
|
595
498
|
return _create_client(config_string, password)
|
|
596
499
|
|
|
597
500
|
|
|
598
|
-
def _create_client(config_string: str, password) ->
|
|
501
|
+
def _create_client(config_string: str, password) -> AasHttpClient | None:
|
|
599
502
|
try:
|
|
600
|
-
connection_settings =
|
|
601
|
-
client =
|
|
503
|
+
connection_settings = AasHttpClient.model_validate_json(config_string)
|
|
504
|
+
client = AasHttpClient(**connection_settings.model_dump())
|
|
602
505
|
except ValidationError as ve:
|
|
603
506
|
raise ValidationError(f"Invalid BaSyx server connection file: {ve}") from ve
|
|
604
507
|
|
|
605
508
|
logger.info(
|
|
606
509
|
f"Using server configuration: '{client.base_url}' | "
|
|
510
|
+
f"API base path: '{client.api_base_path}' | "
|
|
607
511
|
f"timeout: '{client.time_out}' | "
|
|
608
512
|
f"username: '{client.username}' | "
|
|
609
513
|
f"https_proxy: '{client.https_proxy}' | "
|
|
@@ -621,7 +525,7 @@ def _create_client(config_string: str, password) -> AasxServerInterface | None:
|
|
|
621
525
|
return client
|
|
622
526
|
|
|
623
527
|
|
|
624
|
-
def _connect_to_api(client:
|
|
528
|
+
def _connect_to_api(client: AasHttpClient) -> bool:
|
|
625
529
|
start_time = time.time()
|
|
626
530
|
logger.debug(f"Try to connect to REST API '{client.base_url}' for {client.connection_time_out} seconds")
|
|
627
531
|
counter: int = 0
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import aas_http_client.utilities.model_builder as model_builder
|
|
3
|
+
from aas_http_client.client import create_client_by_config, AasHttpClient
|
|
4
|
+
from aas_http_client.wrapper.sdk_wrapper import SdkWrapper, create_wrapper_by_config
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
import json
|
|
7
|
+
import basyx.aas.adapter.json
|
|
8
|
+
from basyx.aas.model import AssetAdministrationShell
|
|
9
|
+
|
|
10
|
+
logger = logging.getLogger(__name__)
|
|
11
|
+
|
|
12
|
+
def start():
|
|
13
|
+
"""Start the demo process."""
|
|
14
|
+
|
|
15
|
+
aas_1 = _create_shell()
|
|
16
|
+
aas_2 = _create_shell()
|
|
17
|
+
|
|
18
|
+
client = _create_client()
|
|
19
|
+
sdk_wrapper = _create_sdk_wrapper()
|
|
20
|
+
|
|
21
|
+
exist_shells = sdk_wrapper.get_shells()
|
|
22
|
+
|
|
23
|
+
for shell in exist_shells:
|
|
24
|
+
logger.warning(f"Delete shell '{shell.id}'")
|
|
25
|
+
sdk_wrapper.delete_shells_by_id(shell.id)
|
|
26
|
+
|
|
27
|
+
sdk_wrapper.post_shells(aas_1)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
aas_dict_string = json.dumps(aas_2, cls=basyx.aas.adapter.json.AASToJsonEncoder)
|
|
31
|
+
aas_dict = json.loads(aas_dict_string)
|
|
32
|
+
client.post_shells(aas_dict)
|
|
33
|
+
|
|
34
|
+
shells = client.get_shells()
|
|
35
|
+
|
|
36
|
+
logger.info(f"Client created successfully. {shells}")
|
|
37
|
+
|
|
38
|
+
def _create_shell() -> AssetAdministrationShell:
|
|
39
|
+
# create an AAS
|
|
40
|
+
aas_short_id: str = model_builder.create_unique_short_id("poc_aas")
|
|
41
|
+
aas = model_builder.create_base_ass(aas_short_id)
|
|
42
|
+
|
|
43
|
+
# create a Submodel
|
|
44
|
+
sm_short_id: str = model_builder.create_unique_short_id("poc_sm")
|
|
45
|
+
submodel = model_builder.create_base_submodel(sm_short_id)
|
|
46
|
+
|
|
47
|
+
# add Submodel to AAS
|
|
48
|
+
model_builder.add_submodel_to_aas(aas, submodel)
|
|
49
|
+
|
|
50
|
+
return aas
|
|
51
|
+
|
|
52
|
+
def _create_client() -> AasHttpClient:
|
|
53
|
+
"""Create client for java servers."""
|
|
54
|
+
|
|
55
|
+
try:
|
|
56
|
+
file = Path("./demo/server_config.json")
|
|
57
|
+
client = create_client_by_config(file, password="")
|
|
58
|
+
except Exception as e:
|
|
59
|
+
logger.error(f"Failed to create client for {file}: {e}")
|
|
60
|
+
pass
|
|
61
|
+
|
|
62
|
+
return client
|
|
63
|
+
|
|
64
|
+
def _create_sdk_wrapper() -> SdkWrapper:
|
|
65
|
+
"""Create client for java servers."""
|
|
66
|
+
|
|
67
|
+
try:
|
|
68
|
+
file = Path("./demo/server_config.json")
|
|
69
|
+
client = create_wrapper_by_config(file, password="")
|
|
70
|
+
except Exception as e:
|
|
71
|
+
logger.error(f"Failed to create client for {file}: {e}")
|
|
72
|
+
pass
|
|
73
|
+
|
|
74
|
+
return client
|