AAS HTTP Client Documentation
Loading...
Searching...
No Matches
test_client.py
Go to the documentation of this file.
1from multiprocessing.sharedctypes import Value
2import pytest
3from pathlib import Path
4from aas_http_client.classes.client.aas_client import create_by_config, AasHttpClient, create_by_dict, create_by_url
5from basyx.aas import model
6import aas_http_client.utilities.model_builder as model_builder
8import json
9import basyx.aas.adapter.json
10from urllib.parse import urlparse
11import logging
12from aas_http_client.demo.logging_handler import initialize_logging
13from aas_http_client.utilities import encoder
14import random
15import json
16
17logger = logging.getLogger(__name__)
18
19JAVA_SERVER_PORTS = [8075]
20PYTHON_SERVER_PORTS = [5080, 80]
21DOTNET_SERVER_PORTS = [5043]
22
23AIMC_SM_ID = "https://fluid40.de/ids/sm/7644_4034_2556_2369"
24SM_ID = "fluid40/sm_http_client_unit_tests"
25SHELL_ID = "fluid40/aas_http_client_unit_tests"
26
27CONFIG_FILES = [
28 "./tests/server_configs/test_java_server_config.json",
29 "./tests/server_configs/test_java_server_alias_config.json",
30 "./tests/server_configs/test_dotnet_server_config.json",
31 "./tests/server_configs/test_python_server_config.json"
32]
33
34# CONFIG_FILES = [
35# "./tests/server_configs/test_dotnet_server_config_local.yml",
36# ]
37
38@pytest.fixture(params=CONFIG_FILES, scope="module")
39def client(request) -> AasHttpClient:
40 try:
41 initialize_logging()
42 file = Path(request.param).resolve()
43
44 if not file.exists():
45 raise FileNotFoundError(f"Configuration file {file} does not exist.")
46
47 client = create_by_config(file)
48
49 if client is None:
50 raise RuntimeError("Failed to create client from configuration file.")
51
52 # Randomly set encoded_ids to True or False for testing both scenarios
53 rand = random.randint(0, 10)
54 if (rand % 2) == 0:
55 client.encoded_ids = True
56
57 except Exception as e:
58 raise RuntimeError("Unable to connect to server.")
59
60
61 if client.shells is None:
62 pytest.skip("Shells API is not available in this client")
63
64 shells = client.shells.get_all_asset_administration_shells()
65 if shells is None:
66 raise RuntimeError("No shells found on server. Please check the server configuration.")
67
68 return client
69
70@pytest.fixture(scope="module")
71def shared_sme_string() -> model.Property:
72 # create a Submodel
73 return model_builder.create_base_submodel_element_property("sme_property_string", model.datatypes.String, "Sample String Value", description="This is a sample string property for unit testing.", display_name="Sample String Property")
74
75@pytest.fixture(scope="module")
76def shared_sme_bool() -> model.Property:
77 # create a Submodel
78 return model_builder.create_base_submodel_element_property("sme_property_bool", model.datatypes.Boolean, True, description="This is a sample boolean property for unit testing.", display_name="Sample Boolean Property")
79
80@pytest.fixture(scope="module")
81def shared_sme_int() -> model.Property:
82 # create a Submodel
83 return model_builder.create_base_submodel_element_property("sme_property_int", model.datatypes.Integer, 262, description="This is a sample integer property for unit testing.", display_name="Sample Integer Property")
84
85@pytest.fixture(scope="module")
86def shared_sme_float() -> model.Property:
87 # create a Submodel
88 return model_builder.create_base_submodel_element_property("sme_property_float", model.datatypes.Float, 262.3, description="This is a sample float property for unit testing.", display_name="Sample Float Property")
89
90@pytest.fixture(scope="module")
91def shared_sme_collection() -> model.SubmodelElementCollection:
92 # create a Submodel
93 values: list[model.SubmodelElement] = []
94 values.append(model_builder.create_base_submodel_element_property("coll_element_1", model.datatypes.Integer, 262, description="This is a sample integer property for unit testing.", display_name="Sample Integer Property"))
95 values.append(model_builder.create_base_submodel_element_property("coll_element_2", model.datatypes.String, "262", description="This is a sample string property for unit testing.", display_name="Sample String Property"))
96 values.append(model_builder.create_base_submodel_element_property("coll_element_3", model.datatypes.Float, 262.3, description="This is a sample float property for unit testing.", display_name="Sample Float Property"))
97
98 return model_builder.create_base_submodel_element_collection("sme_property_collection", values, description="This is a sample collection property for unit testing.", display_name="Sample Collection Property")
99
100@pytest.fixture(scope="module")
101def shared_sm() -> model.Submodel:
102 # create a Submodel
103 return model_builder.create_base_submodel(identifier=SM_ID, id_short="sm_http_client_unit_tests", display_name="Submodel HTTP Client Unit Tests", description="This is a sample Submodel created for unit testing of the AAS HTTP Client.")
104
105@pytest.fixture(scope="module")
106def shared_aas(shared_sm: model.Submodel) -> model.AssetAdministrationShell:
107 # create an AAS
108 aas = model_builder.create_base_aas(identifier=SHELL_ID, id_short="aas_http_client_unit_tests", global_asset_identifier=SHELL_ID, display_name="AAS HTTP Client Unit Tests", description="This is a sample AAS created for unit testing of the AAS HTTP Client.")
109
110 # add Submodel to AAS
111 sdk_tools.add_submodel_to_aas(aas, shared_sm)
112
113 return aas
114
115def test_000a_create_client_by_url(client: AasHttpClient):
116 base_url: str = client.base_url
117 new_client = create_by_url(base_url=base_url)
118 assert new_client is not None
119
120def test_000b_create_client_by_dict(client: AasHttpClient):
121 base_url: str = client.base_url
122
123 config_dict: dict = {
124 "BaseUrl": base_url
125 }
126
127 new_client = create_by_dict(configuration=config_dict)
128 assert new_client is not None
129
130def test_001a_connect(client: AasHttpClient):
131 assert client is not None
132
134 if client.shells is None:
135 pytest.skip("Shells API is not available in this client")
136
137 result = client.shells.get_all_asset_administration_shells()
138 assert result is not None
139 shells = result.get("result", [])
140
141 for shell in shells:
142 shell_id = shell.get("id", "")
143
144 if client.encoded_ids:
145 shell_id = encoder.encode_base_64(shell_id)
146
147 if shell_id:
148 delete_result = client.shells.delete_asset_administration_shell_by_id(shell_id)
149 assert delete_result
150
151 shells_result = client.shells.get_all_asset_administration_shells()
152
153 if shells_result is None:
154 raise RuntimeError("Failed to retrieve shells after deletion.")
155
156 shells = shells_result.get("result", [])
157 assert len(shells) == 0
158
159def test_001c_delete_all_submodels(client: AasHttpClient):
160 if client.submodels is None:
161 pytest.skip("Submodels API is not available in this client")
162
163 result = client.submodels.get_all_submodels()
164 assert result is not None
165 submodels = result.get("result", [])
166
167 for submodel in submodels:
168 submodel_id = submodel.get("id", "")
169
170 if client.encoded_ids:
171 submodel_id = encoder.encode_base_64(submodel_id)
172
173 if submodel_id:
174 delete_result = client.submodels.delete_submodel_by_id(submodel_id)
175 assert delete_result
176
177 submodels_result = client.submodels.get_all_submodels()
178
179 if submodels_result is None:
180 raise RuntimeError("Failed to retrieve submodels after deletion.")
181
182 submodels = submodels_result.get("result", [])
183 assert len(submodels) == 0
184
186 if client.shells is None:
187 pytest.skip("Shells API is not available in this client")
188
189 result = client.shells.get_all_asset_administration_shells()
190 assert result is not None
191 shells = result.get("result", [])
192 assert len(shells) == 0
193
194def test_003_post_asset_administration_shell(client: AasHttpClient, shared_aas: model.AssetAdministrationShell):
195 if client.shells is None:
196 pytest.skip("Shells API is not available in this client")
197
198 aas_data_string = json.dumps(shared_aas, cls=basyx.aas.adapter.json.AASToJsonEncoder)
199 aas_data = json.loads(aas_data_string)
200 result = client.shells.post_asset_administration_shell(aas_data)
201
202 assert result is not None
203 assert result.get("idShort", "") == shared_aas.id_short
204 assert result.get("id", "") == SHELL_ID
205
206 get_result = client.shells.get_all_asset_administration_shells()
207 assert get_result is not None
208 shells = get_result.get("result", [])
209 assert len(shells) == 1
210 assert shells[0].get("idShort", "") == shared_aas.id_short
211 assert shells[0].get("id", "") == SHELL_ID
212 submodels = shells[0].get("submodels", [])
213 assert len(submodels) == 1
214 submodel: dict = submodels[0]
215 assert len(submodel.get("keys", [])) == 1
216 assert submodel.get("keys", [])[0].get("value", "") == SM_ID
217
218def test_004a_get_asset_administration_shell_by_id(client: AasHttpClient, shared_aas: model.AssetAdministrationShell):
219 if client.shells is None:
220 pytest.skip("Shells API is not available in this client")
221
222 shell_id = SHELL_ID
223
224 if client.encoded_ids:
225 shell_id = encoder.encode_base_64(SHELL_ID)
226
227 result = client.shells.get_asset_administration_shell_by_id(shell_id)
228
229 assert result is not None
230 assert result.get("idShort", "") == shared_aas.id_short
231 assert result.get("id", "") == SHELL_ID
232
234 if client.shells is None:
235 pytest.skip("Shells API is not available in this client")
236
237 result = client.shells.get_asset_administration_shell_by_id("non_existent_id")
238
239 assert result is None
240
241def test_005a_put_asset_administration_shell_by_id(client: AasHttpClient, shared_aas: model.AssetAdministrationShell):
242 if client.shells is None:
243 pytest.skip("Shells API is not available in this client")
244
245 assert shared_aas.asset_information is not None
246 assert shared_aas.asset_information.global_asset_id is not None
247
248 aas = model.AssetAdministrationShell(id_=shared_aas.asset_information.global_asset_id, asset_information=shared_aas.asset_information)
249 aas.id_short = shared_aas.id_short
250
251 description_text = "Put description for unit tests"
252 aas.description = model.MultiLanguageTextType({"en": description_text})
253 aas.submodel = shared_aas.submodel # Keep existing submodels
254
255 aas_data_string = json.dumps(aas, cls=basyx.aas.adapter.json.AASToJsonEncoder)
256 aas_data = json.loads(aas_data_string)
257
258 shell_id = SHELL_ID
259
260 if client.encoded_ids:
261 shell_id = encoder.encode_base_64(SHELL_ID)
262
263 result = client.shells.put_asset_administration_shell_by_id(shell_id, aas_data)
264 assert result
265
266 get_result = client.shells.get_asset_administration_shell_by_id(shell_id)
267 assert get_result
268 assert get_result.get("idShort", "") == shared_aas.id_short
269 assert get_result.get("id", "") == SHELL_ID
270 # description must have changed
271 assert get_result.get("description", {})[0].get("text", "") == description_text
272 assert shared_aas.description is not None
273 assert get_result.get("description", {})[0].get("text", "") != shared_aas.description.get("en", "")
274 # submodels must be retained
275 assert len(get_result.get("submodels", [])) == len(shared_aas.submodel)
276
277 # The display name must be empty
278 # NOTE: currently not working in dotnet
279 # assert len(get_result.get("displayName", {})) == 0
280
281 # restore to its original state
282 sm_data_string = json.dumps(shared_aas, cls=basyx.aas.adapter.json.AASToJsonEncoder)
283 sm_data = json.loads(sm_data_string)
284 client.shells.put_asset_administration_shell_by_id(shell_id, sm_data) # Restore original submodel
285
286def test_005b_put_asset_administration_shell_by_id(client: AasHttpClient, shared_aas: model.AssetAdministrationShell):
287 if client.shells is None:
288 pytest.skip("Shells API is not available in this client")
289
290 # put with other ID
291 id_short = "put_short_id"
292 identifier = f"fluid40/{id_short}"
293 asset_info = model_builder.create_base_asset_information(identifier)
294 assert asset_info.global_asset_id == identifier
295
296 aas = model.AssetAdministrationShell(id_=asset_info.global_asset_id, asset_information=asset_info)
297 aas.id_short = id_short
298
299 description_text = {"en": "Updated description for unit tests"}
300 aas.description = model.MultiLanguageTextType(description_text)
301
302 aas_data_string = json.dumps(aas, cls=basyx.aas.adapter.json.AASToJsonEncoder)
303 aas_data = json.loads(aas_data_string)
304
305 shell_id = SHELL_ID
306
307 if client.encoded_ids:
308 shell_id = encoder.encode_base_64(SHELL_ID)
309
310 parsed = urlparse(client.base_url)
311 if parsed.port in PYTHON_SERVER_PORTS:
312 # NOTE: Python server crashes by this test
313 result = False
314 else:
315 result = client.shells.put_asset_administration_shell_by_id(shell_id, aas_data)
316
317 assert not result
318
319 get_result = client.shells.get_asset_administration_shell_by_id(shell_id)
320 assert get_result is not None
321 assert get_result.get("description", {})[0].get("text", "") != description_text
322 assert shared_aas.description is not None
323 assert get_result.get("description", {})[0].get("text", "") == shared_aas.description.get("en", "")
324
326 if client.shells is None:
327 pytest.skip("Shells API is not available in this client")
328
329 shell_id = SHELL_ID
330
331 if client.encoded_ids:
332 shell_id = encoder.encode_base_64(SHELL_ID)
333
334 result = client.shells.get_asset_administration_shell_by_id_reference_aas_repository(shell_id)
335
336 parsed = urlparse(client.base_url)
337 if parsed.port in JAVA_SERVER_PORTS:
338 # NOTE: Basyx java server do not provide this endpoint
339 assert result is None
340 else:
341 assert result is not None
342 keys = result.get("keys", [])
343 assert len(keys) == 1
344 assert keys[0].get("value", "") == SHELL_ID
345
347 if client.shells is None:
348 pytest.skip("Shells API is not available in this client")
349
350 shell_id = SHELL_ID
351 sm_id = SM_ID
352
353 if client.encoded_ids:
354 shell_id = encoder.encode_base_64(SHELL_ID)
355 sm_id = encoder.encode_base_64(SM_ID)
356
357 result = client.shells.get_submodel_by_id_aas_repository(shell_id, sm_id)
358
359 assert result is None
360
361def test_008_get_all_submodels(client: AasHttpClient):
362 if client.submodels is None:
363 pytest.skip("Submodel API is not available in this client")
364
365 result = client.submodels.get_all_submodels()
366 assert result is not None
367 submodels = result.get("result", [])
368 assert len(submodels) == 0
369
370def test_009a_post_submodel(client: AasHttpClient, shared_sm: model.Submodel):
371 if client.submodels is None:
372 pytest.skip("Submodel API is not available in this client")
373
374 sm_data_string = json.dumps(shared_sm, cls=basyx.aas.adapter.json.AASToJsonEncoder)
375 sm_data = json.loads(sm_data_string)
376
377 result = client.submodels.post_submodel(sm_data)
378
379 assert result is not None
380 result_id_short = result.get("idShort", "")
381 assert result_id_short == shared_sm.id_short
382
383 get_result = client.submodels.get_all_submodels()
384 assert get_result is not None
385 submodels = get_result.get("result", [])
386 assert len(submodels) == 1
387 assert submodels[0].get("idShort", "") == shared_sm.id_short
388
389def test_009b_post_submodel(client: AasHttpClient):
390 if client.submodels is None:
391 pytest.skip("Submodel API is not available in this client")
392
393 sm_template_file = Path(f"./tests/test_data/aimc.json").resolve()
394
395 with Path.open(sm_template_file, "r", encoding="utf-8") as f:
396 sm_data = json.load(f)
397
398 result = client.submodels.post_submodel(sm_data)
399
400 assert result is not None
401 result_id = result.get("id", "")
402 assert result_id == AIMC_SM_ID
403
404 get_result = client.submodels.get_all_submodels()
405 assert get_result is not None
406 submodels = get_result.get("result", [])
407 assert len(submodels) == 2
408
409def test_010_get_submodel_by_id_aas_repository(client: AasHttpClient, shared_sm: model.Submodel):
410 if client.shells is None:
411 pytest.skip("Shells API is not available in this client")
412
413 shell_id = SHELL_ID
414 sm_id = SM_ID
415
416 if client.encoded_ids:
417 shell_id = encoder.encode_base_64(SHELL_ID)
418 sm_id = encoder.encode_base_64(SM_ID)
419
420 result = client.shells.get_submodel_by_id_aas_repository(shell_id, sm_id)
421
422 parsed = urlparse(client.base_url)
423 if parsed.port in JAVA_SERVER_PORTS:
424 # NOTE: Basyx java server do not provide this endpoint
425 assert result is None
426 else:
427 assert result is not None
428 result_id_short = result.get("idShort", "")
429 assert result_id_short == shared_sm.id_short
430
431def test_011a_get_submodel_by_id(client: AasHttpClient, shared_sm: model.Submodel):
432 if client.submodels is None:
433 pytest.skip("Submodel API is not available in this client")
434
435 sm_id = SM_ID
436
437 if client.encoded_ids:
438 sm_id = encoder.encode_base_64(SM_ID)
439
440 result = client.submodels.get_submodel_by_id(sm_id)
441
442 assert result is not None
443 result_id_short = result.get("idShort", "")
444 assert result_id_short == shared_sm.id_short
445
446def test_011b_get_submodel_by_id(client: AasHttpClient):
447 if client.submodels is None:
448 pytest.skip("Submodel API is not available in this client")
449
450 result = client.submodels.get_submodel_by_id("non_existent_id")
451
452 assert result is None
453
454def test_011c_get_submodel_by_id(client: AasHttpClient):
455 if client.submodels is None:
456 pytest.skip("Submodel API is not available in this client")
457
458 sm_id = AIMC_SM_ID
459
460 if client.encoded_ids:
461 sm_id = encoder.encode_base_64(AIMC_SM_ID)
462
463 result = client.submodels.get_submodel_by_id(sm_id)
464
465 assert result is not None
466 result_id = result.get("id", "")
467 assert result_id == AIMC_SM_ID
468
469def test_011d_get_submodel_by_id(client: AasHttpClient):
470 if client.submodels is None:
471 pytest.skip("Submodel API is not available in this client")
472
473 sm_id = AIMC_SM_ID
474
475 if client.encoded_ids:
476 sm_id = encoder.encode_base_64(AIMC_SM_ID)
477
478 result = client.submodels.get_submodel_by_id(sm_id, level="core")
479
480 assert result is not None
481 result_id = result.get("id", "")
482 assert result_id == AIMC_SM_ID
483 #assert "submodelElements" not in result
484
485def test_012_patch_submodel_by_id(client: AasHttpClient, shared_sm: model.Submodel):
486 if client.submodels is None:
487 pytest.skip("Submodel API is not available in this client")
488
489 sm = model.Submodel(shared_sm.id_short)
490 sm.id_short = shared_sm.id_short
491
492 description_text = "Patched description for unit tests"
493 sm.description = model.MultiLanguageTextType({"en": description_text})
494
495 sm_data_string = json.dumps(sm, cls=basyx.aas.adapter.json.AASToJsonEncoder)
496 sm_data = json.loads(sm_data_string)
497
498 sm_id = SM_ID
499
500 if client.encoded_ids:
501 sm_id = encoder.encode_base_64(SM_ID)
502
503 result = client.submodels.patch_submodel_by_id(sm_id, sm_data)
504
505 parsed = urlparse(client.base_url)
506 if parsed.port in JAVA_SERVER_PORTS or parsed.port in PYTHON_SERVER_PORTS:
507 # NOTE: Basyx java and python server do not provide this endpoint
508 assert not result
509 else:
510 assert result is True
511
512 get_result = client.submodels.get_submodel_by_id(sm_id)
513 assert get_result is not None
514 assert get_result.get("idShort", "") == shared_sm.id_short
515 assert get_result.get("id", "") == SM_ID
516 # Only the description may change in patch.
517 assert get_result.get("description", {})[0].get("text", "") == description_text
518 assert shared_sm.description is not None
519 assert shared_sm.display_name is not None
520 assert get_result.get("description", {})[0].get("text", "") != shared_sm.description.get("en", "")
521 # The display name must remain the same.
522 assert get_result.get("displayName", {})[0].get("text", "") == shared_sm.display_name.get("en", "")
523
524def test_013_put_submodel_by_id_aas_repository(client: AasHttpClient, shared_sm: model.Submodel):
525 if client.shells is None:
526 pytest.skip("Shells API is not available in this client")
527
528 sm = model.Submodel(SM_ID)
529 sm.id_short = shared_sm.id_short
530
531 description_text = "Put via shell description for unit tests"
532 sm.description = model.MultiLanguageTextType({"en": description_text})
533
534 sm_data_string = json.dumps(sm, cls=basyx.aas.adapter.json.AASToJsonEncoder)
535 sm_data = json.loads(sm_data_string)
536
537 shell_id = SHELL_ID
538 sm_id = SM_ID
539
540 if client.encoded_ids:
541 shell_id = encoder.encode_base_64(SHELL_ID)
542 sm_id = encoder.encode_base_64(SM_ID)
543
544 result = client.shells.put_submodel_by_id_aas_repository(shell_id, sm_id, sm_data)
545
546 parsed = urlparse(client.base_url)
547 if parsed.port in JAVA_SERVER_PORTS:
548 # NOTE: Basyx java server do not provide this endpoint
549 assert not result
550 else:
551 assert result
552
553 get_result = client.shells.get_submodel_by_id_aas_repository(shell_id, sm_id)
554 assert get_result is not None
555 assert get_result.get("idShort", "") == shared_sm.id_short
556 assert get_result.get("id", "") == SM_ID
557 # description must have changed
558 assert get_result.get("description", {})[0].get("text", "") == description_text
559 assert shared_sm.description is not None
560 assert get_result.get("description", {})[0].get("text", "") != shared_sm.description.get("en", "")
561 assert len(get_result.get("displayName", {})) == 0
562
563 # restore to its original state
564 sm_data_string = json.dumps(shared_sm, cls=basyx.aas.adapter.json.AASToJsonEncoder)
565 sm_data = json.loads(sm_data_string)
566 client.shells.put_submodel_by_id_aas_repository(shell_id, sm_id, sm_data) # Restore original submodel
567
568def test_014_put_submodels_by_id(client: AasHttpClient, shared_sm: model.Submodel):
569 if client.submodels is None:
570 pytest.skip("Submodels API is not available in this client")
571
572 sm = model.Submodel(SM_ID)
573 sm.id_short = shared_sm.id_short
574
575 description_text = "Put description for unit tests"
576 sm.description = model.MultiLanguageTextType({"en": description_text})
577
578 sm_data_string = json.dumps(sm, cls=basyx.aas.adapter.json.AASToJsonEncoder)
579 sm_data = json.loads(sm_data_string)
580
581 sm_id = SM_ID
582
583 if client.encoded_ids:
584 sm_id = encoder.encode_base_64(SM_ID)
585
586 result = client.submodels.put_submodels_by_id(sm_id, sm_data)
587
588 assert result is True
589
590 get_result = client.submodels.get_submodel_by_id(sm_id)
591 assert get_result is not None
592 assert get_result.get("idShort", "") == shared_sm.id_short
593 assert get_result.get("id", "") == SM_ID
594 # description must have changed
595 assert get_result.get("description", {})[0].get("text", "") == description_text
596 assert shared_sm.description is not None
597 assert get_result.get("description", {})[0].get("text", "") != shared_sm.description.get("en", "")
598 assert len(get_result.get("displayName", {})) == 0
599
600 # restore to its original state
601 sm_data_string = json.dumps(shared_sm, cls=basyx.aas.adapter.json.AASToJsonEncoder)
602 sm_data = json.loads(sm_data_string)
603 client.submodels.put_submodels_by_id(SM_ID, sm_data) # Restore original submodel
604
605def test_015_get_all_submodel_elements_submodel_repository(client: AasHttpClient, shared_sm: model.Submodel):
606 if client.submodels is None:
607 pytest.skip("Submodels API is not available in this client")
608
609 sm_id = SM_ID
610
611 if client.encoded_ids:
612 sm_id = encoder.encode_base_64(SM_ID)
613
614 submodel_elements = client.submodels.get_all_submodel_elements_submodel_repository(sm_id)
615
616 assert submodel_elements is not None
617 assert len(submodel_elements.get("result", [])) == 0
618
619def test_016a_post_submodel_element_submodel_repo(client: AasHttpClient, shared_sme_string: model.Property):
620 if client.submodels is None:
621 pytest.skip("Submodels API is not available in this client")
622
623 sme_data_string = json.dumps(shared_sme_string, cls=basyx.aas.adapter.json.AASToJsonEncoder)
624 sme_data = json.loads(sme_data_string)
625
626 sm_id = SM_ID
627
628 if client.encoded_ids:
629 sm_id = encoder.encode_base_64(SM_ID)
630
631 result = client.submodels.post_submodel_element_submodel_repo(sm_id, sme_data)
632
633 assert result is not None
634 assert result.get("idShort", "") == shared_sme_string.id_short
635 assert shared_sme_string.description is not None
636 assert shared_sme_string.display_name is not None
637 assert result.get("description", {})[0].get("text", "") == shared_sme_string.description.get("en", "")
638 assert result.get("displayName", {})[0].get("text", "") == shared_sme_string.display_name.get("en", "")
639 assert result.get("value", "") == shared_sme_string.value
640
641 get_result = client.submodels.get_all_submodel_elements_submodel_repository(sm_id)
642 assert get_result is not None
643
644 assert len(get_result.get("result", [])) == 1
645
646def test_016b_post_submodel_element_submodel_repo(client: AasHttpClient, shared_sme_bool: model.Property):
647 if client.submodels is None:
648 pytest.skip("Submodels API is not available in this client")
649
650 sme_data_string = json.dumps(shared_sme_bool, cls=basyx.aas.adapter.json.AASToJsonEncoder)
651 sme_data = json.loads(sme_data_string)
652
653 sm_id = SM_ID
654
655 if client.encoded_ids:
656 sm_id = encoder.encode_base_64(SM_ID)
657
658 result = client.submodels.post_submodel_element_submodel_repo(sm_id, sme_data)
659
660 assert result is not None
661 assert result.get("idShort", "") == shared_sme_bool.id_short
662 assert shared_sme_bool.description is not None
663 assert shared_sme_bool.display_name is not None
664 assert result.get("description", {})[0].get("text", "") == shared_sme_bool.description.get("en", "")
665 assert result.get("displayName", {})[0].get("text", "") == shared_sme_bool.display_name.get("en", "")
666 assert json.loads(result.get("value", "").lower()) == shared_sme_bool.value
667
668 get_result = client.submodels.get_all_submodel_elements_submodel_repository(sm_id)
669 assert get_result is not None
670
671 assert len(get_result.get("result", [])) == 2
672
673def test_016c_post_submodel_element_submodel_repo(client: AasHttpClient, shared_sme_int: model.Property):
674 if client.submodels is None:
675 pytest.skip("Submodels API is not available in this client")
676
677 sme_data_string = json.dumps(shared_sme_int, cls=basyx.aas.adapter.json.AASToJsonEncoder)
678 sme_data = json.loads(sme_data_string)
679
680 sm_id = SM_ID
681
682 if client.encoded_ids:
683 sm_id = encoder.encode_base_64(SM_ID)
684
685 result = client.submodels.post_submodel_element_submodel_repo(sm_id, sme_data)
686
687 assert result is not None
688 assert result.get("idShort", "") == shared_sme_int.id_short
689 assert shared_sme_int.description is not None
690 assert shared_sme_int.display_name is not None
691 assert result.get("description", {})[0].get("text", "") == shared_sme_int.description.get("en", "")
692 assert result.get("displayName", {})[0].get("text", "") == shared_sme_int.display_name.get("en", "")
693 assert int(result.get("value", "")) == shared_sme_int.value
694
695 get_result = client.submodels.get_all_submodel_elements_submodel_repository(sm_id)
696 assert get_result is not None
697
698 assert len(get_result.get("result", [])) == 3
699
700def test_016d_post_submodel_element_submodel_repo(client: AasHttpClient, shared_sme_float: model.Property):
701 if client.submodels is None:
702 pytest.skip("Submodels API is not available in this client")
703
704 sme_data_string = json.dumps(shared_sme_float, cls=basyx.aas.adapter.json.AASToJsonEncoder)
705 sme_data = json.loads(sme_data_string)
706
707 sm_id = SM_ID
708
709 if client.encoded_ids:
710 sm_id = encoder.encode_base_64(SM_ID)
711
712 result = client.submodels.post_submodel_element_submodel_repo(sm_id, sme_data)
713
714 assert result is not None
715 assert result.get("idShort", "") == shared_sme_float.id_short
716 assert shared_sme_float.description is not None
717 assert shared_sme_float.display_name is not None
718 assert result.get("description", {})[0].get("text", "") == shared_sme_float.description.get("en", "")
719 assert result.get("displayName", {})[0].get("text", "") == shared_sme_float.display_name.get("en", "")
720 assert float(result.get("value", "")) == shared_sme_float.value
721
722 get_result = client.submodels.get_all_submodel_elements_submodel_repository(sm_id)
723 assert get_result is not None
724
725 assert len(get_result.get("result", [])) == 4
726
727def test_017a_get_submodel_element_by_path_submodel_repo(client: AasHttpClient, shared_sme_string: model.Property):
728 if client.submodels is None:
729 pytest.skip("Submodels API is not available in this client")
730
731 sm_id = SM_ID
732
733 if client.encoded_ids:
734 sm_id = encoder.encode_base_64(SM_ID)
735
736 result = client.submodels.get_submodel_element_by_path_submodel_repo(sm_id, shared_sme_string.id_short)
737
738 assert result is not None
739 assert result.get("idShort", "") == shared_sme_string.id_short
740 assert shared_sme_string.description is not None
741 assert shared_sme_string.display_name is not None
742 assert result.get("description", {})[0].get("text", "") == shared_sme_string.description.get("en", "")
743 assert result.get("displayName", {})[0].get("text", "") == shared_sme_string.display_name.get("en", "")
744 assert result.get("value", "") == shared_sme_string.value
745
746def test_017b_get_submodel_element_by_path_submodel_repo(client: AasHttpClient, shared_sme_bool: model.Property):
747 if client.submodels is None:
748 pytest.skip("Submodels API is not available in this client")
749
750 sm_id = SM_ID
751
752 if client.encoded_ids:
753 sm_id = encoder.encode_base_64(SM_ID)
754
755 result = client.submodels.get_submodel_element_by_path_submodel_repo(sm_id, shared_sme_bool.id_short)
756
757 assert result is not None
758 assert result.get("idShort", "") == shared_sme_bool.id_short
759 assert shared_sme_bool.description is not None
760 assert shared_sme_bool.display_name is not None
761 assert result.get("description", {})[0].get("text", "") == shared_sme_bool.description.get("en", "")
762 assert result.get("displayName", {})[0].get("text", "") == shared_sme_bool.display_name.get("en", "")
763 assert json.loads(result.get("value", "").lower()) == shared_sme_bool.value
764
765def test_017c_get_submodel_element_by_path_submodel_repo(client: AasHttpClient, shared_sme_int: model.Property):
766 if client.submodels is None:
767 pytest.skip("Submodels API is not available in this client")
768
769 sm_id = SM_ID
770
771 if client.encoded_ids:
772 sm_id = encoder.encode_base_64(SM_ID)
773
774 result = client.submodels.get_submodel_element_by_path_submodel_repo(sm_id, shared_sme_int.id_short)
775
776 assert result is not None
777 assert result.get("idShort", "") == shared_sme_int.id_short
778 assert shared_sme_int.description is not None
779 assert shared_sme_int.display_name is not None
780 assert result.get("description", {})[0].get("text", "") == shared_sme_int.description.get("en", "")
781 assert result.get("displayName", {})[0].get("text", "") == shared_sme_int.display_name.get("en", "")
782 assert int(result.get("value", "")) == shared_sme_int.value
783
784def test_017d_get_submodel_element_by_path_submodel_repo(client: AasHttpClient, shared_sme_float: model.Property):
785 if client.submodels is None:
786 pytest.skip("Submodels API is not available in this client")
787
788 sm_id = SM_ID
789
790 if client.encoded_ids:
791 sm_id = encoder.encode_base_64(SM_ID)
792
793 result = client.submodels.get_submodel_element_by_path_submodel_repo(sm_id, shared_sme_float.id_short)
794
795 assert result is not None
796 assert result.get("idShort", "") == shared_sme_float.id_short
797 assert shared_sme_float.description is not None
798 assert shared_sme_float.display_name is not None
799 assert result.get("description", {})[0].get("text", "") == shared_sme_float.description.get("en", "")
800 assert result.get("displayName", {})[0].get("text", "") == shared_sme_float.display_name.get("en", "")
801 assert float(result.get("value", "")) == shared_sme_float.value
802
803def test_018a_patch_submodel_element_by_path_value_only_submodel_repo(client: AasHttpClient, shared_sme_string: model.Property):
804 if client.submodels is None:
805 pytest.skip("Submodels API is not available in this client")
806
807 new_value = "Patched String Value"
808
809 sm_id = SM_ID
810
811 if client.encoded_ids:
812 sm_id = encoder.encode_base_64(SM_ID)
813
814 submodel_element = client.submodels.get_submodel_element_by_path_submodel_repo(sm_id, shared_sme_string.id_short)
815 assert submodel_element is not None
816
817 old_value = submodel_element.get("value", "")
818
819 result = client.submodels.patch_submodel_element_by_path_value_only_submodel_repo(sm_id, shared_sme_string.id_short, new_value)
820
821 parsed = urlparse(client.base_url)
822 if parsed.port in PYTHON_SERVER_PORTS:
823 # NOTE: python server do not provide this endpoint
824 assert result is False
825 else:
826 assert result is True
827
828 get_result = client.submodels.get_submodel_element_by_path_submodel_repo(sm_id, shared_sme_string.id_short)
829
830 assert get_result is not None
831 assert get_result.get("idShort", "") == shared_sme_string.id_short
832 assert get_result.get("value", "") == new_value
833 assert shared_sme_string.description is not None
834 assert shared_sme_string.display_name is not None
835 assert get_result.get("description", {})[0].get("text", "") == shared_sme_string.description.get("en", "")
836 assert get_result.get("displayName", {})[0].get("text", "") == shared_sme_string.display_name.get("en", "")
837 assert get_result.get("value", "") != old_value
838
839def test_018b_patch_submodel_element_by_path_value_only_submodel_repo(client: AasHttpClient, shared_sme_bool: model.Property):
840 if client.submodels is None:
841 pytest.skip("Submodels API is not available in this client")
842
843 new_value = "false"
844
845 sm_id = SM_ID
846
847 if client.encoded_ids:
848 sm_id = encoder.encode_base_64(SM_ID)
849
850 submodel_element = client.submodels.get_submodel_element_by_path_submodel_repo(sm_id, shared_sme_bool.id_short)
851 assert submodel_element is not None
852
853 old_value = submodel_element.get("value", "")
854
855 result = client.submodels.patch_submodel_element_by_path_value_only_submodel_repo(sm_id, shared_sme_bool.id_short, new_value)
856
857 parsed = urlparse(client.base_url)
858 if parsed.port in PYTHON_SERVER_PORTS:
859 # NOTE: python server do not provide this endpoint
860 assert result is False
861 else:
862 assert result is True
863
864 get_result = client.submodels.get_submodel_element_by_path_submodel_repo(sm_id, shared_sme_bool.id_short)
865
866 assert get_result is not None
867 assert get_result.get("idShort", "") == shared_sme_bool.id_short
868 assert json.loads(get_result.get("value", "").lower()) == json.loads(new_value)
869 assert shared_sme_bool.description is not None
870 assert shared_sme_bool.display_name is not None
871 assert get_result.get("description", {})[0].get("text", "") == shared_sme_bool.description.get("en", "")
872 assert get_result.get("displayName", {})[0].get("text", "") == shared_sme_bool.display_name.get("en", "")
873 assert get_result.get("value", "").lower() != old_value.lower()
874
875def test_018c_patch_submodel_element_by_path_value_only_submodel_repo(client: AasHttpClient, shared_sme_int: model.Property):
876 if client.submodels is None:
877 pytest.skip("Submodels API is not available in this client")
878
879 new_value = "263"
880
881 sm_id = SM_ID
882
883 if client.encoded_ids:
884 sm_id = encoder.encode_base_64(SM_ID)
885
886 submodel_element = client.submodels.get_submodel_element_by_path_submodel_repo(sm_id, shared_sme_int.id_short)
887 assert submodel_element is not None
888
889 old_value = submodel_element.get("value", "")
890
891 result = client.submodels.patch_submodel_element_by_path_value_only_submodel_repo(sm_id, shared_sme_int.id_short, new_value)
892
893 parsed = urlparse(client.base_url)
894 if parsed.port in PYTHON_SERVER_PORTS:
895 # NOTE: python server do not provide this endpoint
896 assert result is False
897 else:
898 assert result is True
899
900 get_result = client.submodels.get_submodel_element_by_path_submodel_repo(sm_id, shared_sme_int.id_short)
901
902 assert get_result is not None
903 assert get_result.get("idShort", "") == shared_sme_int.id_short
904 assert int(get_result.get("value", "")) == int(new_value)
905 assert shared_sme_int.description is not None
906 assert shared_sme_int.display_name is not None
907 assert get_result.get("description", {})[0].get("text", "") == shared_sme_int.description.get("en", "")
908 assert get_result.get("displayName", {})[0].get("text", "") == shared_sme_int.display_name.get("en", "")
909 assert int(get_result.get("value", "")) != int(old_value)
910
911def test_018d_patch_submodel_element_by_path_value_only_submodel_repo(client: AasHttpClient, shared_sme_float: model.Property):
912 if client.submodels is None:
913 pytest.skip("Submodels API is not available in this client")
914
915 new_value = "262.1"
916
917 sm_id = SM_ID
918
919 if client.encoded_ids:
920 sm_id = encoder.encode_base_64(SM_ID)
921
922 submodel_element = client.submodels.get_submodel_element_by_path_submodel_repo(sm_id, shared_sme_float.id_short)
923 assert submodel_element is not None
924
925 old_value = submodel_element.get("value", "")
926
927 result = client.submodels.patch_submodel_element_by_path_value_only_submodel_repo(sm_id, shared_sme_float.id_short, new_value)
928
929 parsed = urlparse(client.base_url)
930 if parsed.port in PYTHON_SERVER_PORTS:
931 # NOTE: python server do not provide this endpoint
932 assert result is False
933 else:
934 assert result is True
935
936 get_result = client.submodels.get_submodel_element_by_path_submodel_repo(sm_id, shared_sme_float.id_short)
937
938 assert get_result is not None
939 assert get_result.get("idShort", "") == shared_sme_float.id_short
940 assert float(get_result.get("value", "")) == float(new_value)
941 assert shared_sme_float.description is not None
942 assert shared_sme_float.display_name is not None
943 assert get_result.get("description", {})[0].get("text", "") == shared_sme_float.description.get("en", "")
944 assert get_result.get("displayName", {})[0].get("text", "") == shared_sme_float.display_name.get("en", "")
945 assert float(get_result.get("value", "")) != float(old_value)
946
948 if client.submodels is None:
949 pytest.skip("Submodels API is not available in this client")
950
951 submodel_element_list = model.SubmodelElementList(id_short="sme_list_1", type_value_list_element=model.Property, value_type_list_element=model.datatypes.String)
952 submodel_element_list_dict = sdk_tools.convert_to_dict(submodel_element_list)
953 assert submodel_element_list_dict is not None
954
955 sm_id = SM_ID
956
957 if client.encoded_ids:
958 sm_id = encoder.encode_base_64(SM_ID)
959
960 post_list_element_result = client.submodels.post_submodel_element_submodel_repo(sm_id, submodel_element_list_dict)
961
962 assert post_list_element_result is not None
963
964 property = model_builder.create_base_submodel_element_property(None, model.datatypes.String, "Value in List")
965 property_dict = sdk_tools.convert_to_dict(property)
966 assert property_dict is not None
967 assert "idShort" not in property_dict
968
969 result = client.submodels.post_submodel_element_by_path_submodel_repo(sm_id, submodel_element_list.id_short, property_dict)
970
971 assert result is not None
972 assert "idShort" not in result # idShort was deleted
973
974 submodel = client.submodels.get_submodel_by_id(sm_id)
975
976 assert submodel is not None
977 elements = submodel.get("submodelElements", [])
978 assert len(elements) == 5 # 4 previous properties + 1 list
979 assert elements[4].get("idShort", "") == submodel_element_list.id_short
980 list_elements = elements[4].get("value", [])
981 assert len(list_elements) == 1
982 assert list_elements[0].get("idShort", "") == ""
983 assert list_elements[0].get("value", "") == property.value
984
985
987 if client.submodels is None:
988 pytest.skip("Submodels API is not available in this client")
989
990 submodel_element_collection = model.SubmodelElementCollection(id_short="sme_collection_1")
991 submodel_element_collection_dict = sdk_tools.convert_to_dict(submodel_element_collection)
992 assert submodel_element_collection_dict is not None
993
994 sm_id = SM_ID
995
996 if client.encoded_ids:
997 sm_id = encoder.encode_base_64(SM_ID)
998
999 first_result = client.submodels.post_submodel_element_submodel_repo(sm_id, submodel_element_collection_dict)
1000
1001 assert first_result is not None
1002
1003 property = model_builder.create_base_submodel_element_property("sme_property_in_collection", model.datatypes.String, "Value in List")
1004 property_dict = sdk_tools.convert_to_dict(property)
1005 assert property_dict is not None
1006
1007 result = client.submodels.post_submodel_element_by_path_submodel_repo(sm_id, submodel_element_collection.id_short, property_dict)
1008
1009 assert result is not None
1010 assert result["idShort"] == property.id_short
1011
1012 submodel = client.submodels.get_submodel_by_id(sm_id)
1013
1014 assert submodel is not None
1015 elements = submodel.get("submodelElements", [])
1016 assert len(elements) == 6
1017 assert elements[5].get("idShort", "") == submodel_element_collection.id_short
1018 list_elements = elements[5].get("value", [])
1019 assert len(list_elements) == 1
1020 assert list_elements[0].get("idShort", "") == property.id_short
1021 assert list_elements[0].get("value", "") == property.value
1022
1023 base_url: str = client.base_url
1024 new_client = create_by_url(base_url=base_url)
1025 assert new_client is not None
1026 assert new_client.submodels is not None
1027
1028 sm = new_client.submodels.get_submodel_by_id(AIMC_SM_ID)
1029 assert sm is None
1030
1031 decoded_id = encoder.encode_base_64(AIMC_SM_ID)
1032 decoded_sm = new_client.submodels.get_submodel_by_id(decoded_id)
1033 assert decoded_sm is not None
1034 assert decoded_sm.get("id", "") == AIMC_SM_ID
1035
1036def test_020b_encoded_ids(client: AasHttpClient):
1037 base_url: str = client.base_url
1038 new_client = create_by_url(base_url=base_url)
1039 assert new_client is not None
1040 assert new_client.shells is not None
1041
1042 sm = new_client.shells.get_asset_administration_shell_by_id(SHELL_ID)
1043 assert sm is None
1044
1045 decoded_id = encoder.encode_base_64(SHELL_ID)
1046 decoded_sm = new_client.shells.get_asset_administration_shell_by_id(decoded_id)
1047 assert decoded_sm is not None
1048 assert decoded_sm.get("id", "") == SHELL_ID
1049
1051 if client.experimental is None:
1052 pytest.skip("Experimental API is not available in this client")
1053
1054 if client.submodels is None:
1055 pytest.skip("Submodels API is not available in this client")
1056
1057 parsed = urlparse(client.base_url)
1058 if parsed.port in JAVA_SERVER_PORTS or parsed.port in PYTHON_SERVER_PORTS:
1059 # NOTE: python server implementation differs
1060 # NOTE: Basyx java server do not provide this endpoint
1061 return
1062
1063 sm_id = SM_ID
1064
1065 if client.encoded_ids:
1066 sm_id = encoder.encode_base_64(SM_ID)
1067
1068 file_sme = model.File("file_sme", content_type="application/pdf")
1069 file_post_result = client.submodels.post_submodel_element_submodel_repo(sm_id, sdk_tools.convert_to_dict(file_sme))
1070 assert file_post_result is not None
1071
1072 filename = "https.pdf"
1073 file = Path(f"./tests/test_data/{filename}").resolve()
1074 result = client.experimental.post_file_by_path_submodel_repo(sm_id, file_sme.id_short, file)
1075 assert result is True
1076
1077 result_sme = client.submodels.get_submodel_element_by_path_submodel_repo(sm_id, file_sme.id_short)
1078
1079 assert result_sme is not None
1080 assert result_sme.get("idShort", "") == file_sme.id_short
1081 assert result_sme.get("contentType", "") == file_sme.content_type
1082 assert "value" in result_sme
1083 assert result_sme.get("value", "") == f"/{filename}"
1084
1086 if client.experimental is None:
1087 pytest.skip("Experimental API is not available in this client")
1088
1089 parsed = urlparse(client.base_url)
1090 if parsed.port in JAVA_SERVER_PORTS or parsed.port in PYTHON_SERVER_PORTS:
1091 # NOTE: python server implementation differs
1092 # NOTE: Basyx java server do not provide this endpoint
1093 return
1094
1095 sm_id = SM_ID
1096
1097 if client.encoded_ids:
1098 sm_id = encoder.encode_base_64(SM_ID)
1099
1100 result = client.experimental.get_file_by_path_submodel_repo(sm_id, "file_sme")
1101 assert result is not None
1102 assert len(result) > 0
1103 assert result.startswith(b"%PDF-1.7")
1104
1106 if client.experimental is None:
1107 pytest.skip("Experimental API is not available in this client")
1108
1109 if client.submodels is None:
1110 pytest.skip("Submodels API is not available in this client")
1111
1112 parsed = urlparse(client.base_url)
1113 if parsed.port in JAVA_SERVER_PORTS or parsed.port in PYTHON_SERVER_PORTS:
1114 # NOTE: python server implementation differs
1115 # NOTE: Basyx java server do not provide this endpoint
1116 return
1117
1118 sm_id = SM_ID
1119
1120 if client.encoded_ids:
1121 sm_id = encoder.encode_base_64(SM_ID)
1122
1123 filename = "aimc.json"
1124 file = Path(f"./tests/test_data/{filename}").resolve()
1125 result = client.experimental.put_file_by_path_submodel_repo(sm_id, "file_sme", file)
1126 assert result is True
1127
1128 get_result = client.experimental.get_file_by_path_submodel_repo(sm_id, "file_sme")
1129 assert get_result is not None
1130 assert len(get_result) > 0
1131 assert get_result.startswith(b"{\n")
1132
1133 result_sme = client.submodels.get_submodel_element_by_path_submodel_repo(sm_id, "file_sme")
1134 assert result_sme is not None
1135 assert "value" in result_sme
1136 assert result_sme.get("value", "") == f"/{filename}"
1137
1139 if client.experimental is None:
1140 pytest.skip("Experimental API is not available in this client")
1141
1142 if client.submodels is None:
1143 pytest.skip("Submodels API is not available in this client")
1144
1145 parsed = urlparse(client.base_url)
1146 if parsed.port in JAVA_SERVER_PORTS or parsed.port in PYTHON_SERVER_PORTS:
1147 # NOTE: python server do not provide this endpoint
1148 return
1149
1150 sm_id = SM_ID
1151
1152 if client.encoded_ids:
1153 sm_id = encoder.encode_base_64(SM_ID)
1154
1155 result = client.experimental.delete_file_by_path_submodel_repo(sm_id, "file_sme")
1156 assert result is True
1157
1158 get_result = client.experimental.get_file_by_path_submodel_repo(sm_id, "file_sme")
1159 assert get_result is None
1160
1161 result_sme = client.submodels.get_submodel_element_by_path_submodel_repo(sm_id, "file_sme")
1162 assert result_sme is not None
1163 assert "value" in result_sme
1164 assert result_sme.get("value", "") == None
1165
1166def test_025_get_thumbnail_aas_repository(client: AasHttpClient):
1167 if client.shells is None:
1168 pytest.skip("Shells API is not available in this client")
1169
1170 parsed = urlparse(client.base_url)
1171 if parsed.port in PYTHON_SERVER_PORTS:
1172 # NOTE: python server implementation differs
1173 return
1174
1175 shell_id = SHELL_ID
1176
1177 if client.encoded_ids:
1178 shell_id = encoder.encode_base_64(SHELL_ID)
1179
1180 result = client.shells.get_thumbnail_aas_repository(shell_id)
1181 assert result is None
1182
1183
1184
1185def test_026_put_thumbnail_aas_repository(client: AasHttpClient):
1186 if client.shells is None:
1187 pytest.skip("Shells API is not available in this client")
1188
1189 parsed = urlparse(client.base_url)
1190 if parsed.port in PYTHON_SERVER_PORTS:
1191 # NOTE: python server implementation differs
1192 return
1193
1194 shell_id = SHELL_ID
1195
1196 if client.encoded_ids:
1197 shell_id = encoder.encode_base_64(SHELL_ID)
1198
1199 filename = "Pen_Machine.png"
1200 file = Path(f"./tests/test_data/{filename}").resolve()
1201
1202 result = client.shells.put_thumbnail_aas_repository(shell_id, file.name, file)
1203 assert result is True
1204
1205def test_027_get_thumbnail_aas_repository(client: AasHttpClient):
1206 if client.shells is None:
1207 pytest.skip("Shells API is not available in this client")
1208
1209 parsed = urlparse(client.base_url)
1210 if parsed.port in PYTHON_SERVER_PORTS:
1211 # NOTE: python server implementation differs
1212 return
1213
1214 shell_id = SHELL_ID
1215
1216 if client.encoded_ids:
1217 shell_id = encoder.encode_base_64(SHELL_ID)
1218
1219 result = client.shells.get_thumbnail_aas_repository(shell_id)
1220 assert result is not None
1221 assert len(result) > 0
1222 assert result.startswith(b"\x89PNG\r\n\x1a\n")
1223
1225 if client.shells is None:
1226 pytest.skip("Shells API is not available in this client")
1227
1228 parsed = urlparse(client.base_url)
1229 if parsed.port in PYTHON_SERVER_PORTS:
1230 # NOTE: python server do not provide this endpoint
1231 return
1232
1233 shell_id = SHELL_ID
1234
1235 if client.encoded_ids:
1236 shell_id = encoder.encode_base_64(SHELL_ID)
1237
1238 result = client.shells.delete_thumbnail_aas_repository(shell_id)
1239 assert result is True
1240
1241 get_result = client.shells.get_thumbnail_aas_repository(shell_id)
1242 assert get_result is None
1243
1245 if client.shells is None:
1246 pytest.skip("Shells API is not available in this client")
1247
1248 parsed = urlparse(client.base_url)
1249 if parsed.port in PYTHON_SERVER_PORTS:
1250 # NOTE: python server implementation differs
1251 return
1252
1253 shell_id = SHELL_ID
1254
1255 if client.encoded_ids:
1256 shell_id = encoder.encode_base_64(SHELL_ID)
1257
1258 filename = "Pen_Machine.png"
1259 file = Path(f"./tests/test_data/{filename}").resolve()
1260
1261 with file.open("rb") as f:
1262 file_octet_stream = f.read()
1263
1264 result = client.shells.put_thumbnail_aas_repository_stream(shell_id, file.name, file_octet_stream, "image/png")
1265 assert result is True
1266
1267 get_result = client.shells.get_thumbnail_aas_repository(shell_id)
1268 assert get_result is not None
1269 assert len(get_result) > 0
1270 assert get_result.startswith(b"\x89PNG\r\n\x1a\n")
1271
1272 delete_result = client.shells.delete_thumbnail_aas_repository(shell_id)
1273 assert delete_result is True
1274
1275 get_result = client.shells.get_thumbnail_aas_repository(shell_id)
1276 assert get_result is None
1277
1279 if client.shells is None:
1280 pytest.skip("Shells API is not available in this client")
1281
1282 shell_id = SHELL_ID
1283
1284 if client.encoded_ids:
1285 shell_id = encoder.encode_base_64(SHELL_ID)
1286
1287 result = client.shells.get_all_submodel_references_aas_repository(shell_id)
1288 assert result is not None
1289 references = result.get("result", [])
1290 assert len(references) == 1
1291
1293 if client.shells is None:
1294 pytest.skip("Shells API is not available in this client")
1295
1296 shell_id = SHELL_ID
1297
1298 if client.encoded_ids:
1299 shell_id = encoder.encode_base_64(SHELL_ID)
1300
1301 id = "temp_sm_id"
1302 id_short = "TempSM"
1303 temp_sml_ref = model.ModelReference.from_referable(model_builder.create_base_submodel(identifier=id, id_short=id_short))
1304
1305 result = client.shells.post_submodel_reference_aas_repository(shell_id, sdk_tools.convert_to_dict(temp_sml_ref))
1306
1307 assert result is not None
1308 assert len(result.get("keys", [])) > 0
1309 key: dict = result.get("keys", [])[0]
1310 assert key.get("value", "") == id
1311 assert key.get("type", "") == "Submodel"
1312
1313 check_result = client.shells.get_all_submodel_references_aas_repository(shell_id)
1314 assert check_result is not None
1315 check_references = check_result.get("result", [])
1316 assert len(check_references) == 2
1317
1319 if client.shells is None:
1320 pytest.skip("Submodels API is not available in this client")
1321
1322 shell_id = SHELL_ID
1323 sm_id = "temp_sm_id"
1324
1325 if client.encoded_ids:
1326 shell_id = encoder.encode_base_64(SHELL_ID)
1327 sm_id = encoder.encode_base_64(sm_id)
1328
1329 result = client.shells.delete_submodel_reference_by_id_aas_repository(shell_id, sm_id)
1330
1331 assert result is True
1332
1333 get_result = client.shells.get_all_submodel_references_aas_repository(shell_id)
1334 assert get_result is not None
1335 references = get_result.get("result", [])
1336 assert len(references) == 1
1337
1338def test_032_put_submodel_element_by_path_submodel_repo(client: AasHttpClient, shared_sme_string: model.Property):
1339 if client.submodels is None:
1340 pytest.skip("Submodels API is not available in this client")
1341
1342 sm_id = SM_ID
1343
1344 if client.encoded_ids:
1345 sm_id = encoder.encode_base_64(SM_ID)
1346
1347 get_result = client.submodels.get_submodel_element_by_path_submodel_repo(sm_id, shared_sme_string.id_short)
1348 assert get_result is not None
1349 old_value = get_result.get("value", "")
1350
1351 new_value = "New Value via PUT"
1352
1353 sme_data_string = json.dumps(shared_sme_string, cls=basyx.aas.adapter.json.AASToJsonEncoder)
1354 sme_data = json.loads(sme_data_string)
1355 sme_data["value"] = new_value
1356
1357 result = client.submodels.put_submodel_element_by_path_submodel_repo(sm_id, shared_sme_string.id_short, sme_data)
1358
1359 assert result is True
1360
1361 get_result = client.submodels.get_submodel_element_by_path_submodel_repo(sm_id, shared_sme_string.id_short)
1362
1363 assert get_result is not None
1364 assert get_result.get("idShort", "") == shared_sme_string.id_short
1365 assert get_result.get("value", "") == new_value
1366 assert get_result.get("value", "") != old_value
1367 assert shared_sme_string.description is not None
1368 assert shared_sme_string.display_name is not None
1369 assert get_result.get("description", {})[0].get("text", "") == shared_sme_string.description.get("en", "")
1370 assert get_result.get("displayName", {})[0].get("text", "") == shared_sme_string.display_name.get("en", "")
1371
1372 # restore original value
1373 sme_data["value"] = "Sample String Value"
1374 result = client.submodels.put_submodel_element_by_path_submodel_repo(sm_id, shared_sme_string.id_short, sme_data)
1375
1376def test_033a_get_submodel_element_by_path_value_only_submodel_repo(client: AasHttpClient, shared_sme_string: model.Property):
1377 if client.submodels is None:
1378 pytest.skip("Submodels API is not available in this client")
1379
1380 sm_id = SM_ID
1381
1382 if client.encoded_ids:
1383 sm_id = encoder.encode_base_64(SM_ID)
1384
1385 value = client.submodels.get_submodel_element_by_path_value_only_submodel_repo(sm_id, shared_sme_string.id_short)
1386
1387 parsed = urlparse(client.base_url)
1388 if parsed.port in PYTHON_SERVER_PORTS:
1389 # NOTE: python server do not provide this endpoint
1390 assert value is None
1391 return
1392
1393 assert value is not None
1394
1395 sm_data = client.submodels.get_submodel_element_by_path_submodel_repo(sm_id, shared_sme_string.id_short)
1396 assert sm_data is not None
1397 assert value == sm_data.get("value", "")
1398
1399def test_033b_get_submodel_element_by_path_value_only_submodel_repo(client: AasHttpClient, shared_sme_int: model.Property):
1400 if client.submodels is None:
1401 pytest.skip("Submodels API is not available in this client")
1402
1403 sm_id = SM_ID
1404
1405 if client.encoded_ids:
1406 sm_id = encoder.encode_base_64(SM_ID)
1407
1408 value = client.submodels.get_submodel_element_by_path_value_only_submodel_repo(sm_id, shared_sme_int.id_short)
1409
1410 parsed = urlparse(client.base_url)
1411 if parsed.port in PYTHON_SERVER_PORTS:
1412 # NOTE: python server do not provide this endpoint
1413 assert value is None
1414 return
1415
1416 assert value is not None
1417
1418 sm_data = client.submodels.get_submodel_element_by_path_submodel_repo(sm_id, shared_sme_int.id_short)
1419 assert sm_data is not None
1420 assert int(value) == int(sm_data.get("value", ""))
1421
1422def test_033c_get_submodel_element_by_path_value_only_submodel_repo(client: AasHttpClient, shared_sme_float: model.Property):
1423 if client.submodels is None:
1424 pytest.skip("Submodels API is not available in this client")
1425
1426 sm_id = SM_ID
1427
1428 if client.encoded_ids:
1429 sm_id = encoder.encode_base_64(SM_ID)
1430
1431 value = client.submodels.get_submodel_element_by_path_value_only_submodel_repo(sm_id, shared_sme_float.id_short)
1432
1433 parsed = urlparse(client.base_url)
1434 if parsed.port in PYTHON_SERVER_PORTS:
1435 # NOTE: python server do not provide this endpoint
1436 assert value is None
1437 return
1438
1439 assert value is not None
1440
1441 sm_data = client.submodels.get_submodel_element_by_path_submodel_repo(sm_id, shared_sme_float.id_short)
1442 assert sm_data is not None
1443 assert float(value) == float(sm_data.get("value", ""))
1444
1445def test_033d_get_submodel_element_by_path_value_only_submodel_repo(client: AasHttpClient, shared_sme_bool: model.Property):
1446 if client.submodels is None:
1447 pytest.skip("Submodels API is not available in this client")
1448
1449 sm_id = SM_ID
1450
1451 if client.encoded_ids:
1452 sm_id = encoder.encode_base_64(SM_ID)
1453
1454 value = client.submodels.get_submodel_element_by_path_value_only_submodel_repo(sm_id, shared_sme_bool.id_short)
1455
1456 parsed = urlparse(client.base_url)
1457 if parsed.port in PYTHON_SERVER_PORTS:
1458 # NOTE: python server do not provide this endpoint
1459 assert value is None
1460 return
1461
1462 assert value is not None
1463
1464 sm_data = client.submodels.get_submodel_element_by_path_submodel_repo(sm_id, shared_sme_bool.id_short)
1465 assert sm_data is not None
1466 #assert bool(value) == bool(sm_data.get("value", ""))
1467
1468# def test_033e_get_submodel_element_by_path_value_only_submodel_repo(client: AasHttpClient, shared_sme_collection: model.SubmodelElementCollection):
1469# if client.submodels is None:
1470# pytest.skip("Submodels API is not available in this client")
1471
1472# post_result = client.submodels.post_submodel_element_submodel_repo(SM_ID, sdk_tools.convert_to_dict(shared_sme_collection))
1473# assert post_result is not None
1474
1475# sm_id = SM_ID
1476
1477# if client.encoded_ids:
1478# sm_id = encoder.encode_base_64(SM_ID)
1479
1480# value = client.submodels.get_submodel_element_by_path_value_only_submodel_repo(sm_id, shared_sme_collection.id_short)
1481
1482# parsed = urlparse(client.base_url)
1483# if parsed.port in PYTHON_SERVER_PORTS:
1484# # NOTE: python server do not provide this endpoint
1485# assert value is None
1486# return
1487
1488# assert value is not None
1489
1490# sm_data = client.submodels.get_submodel_element_by_path_submodel_repo(sm_id, shared_sme_collection.id_short)
1491# assert sm_data is not None
1492# assert value == sm_data.get("value", "")
1493# assert bool(value) == bool(sm_data.get("value", ""))
1494
1495def test_034_get_submodel_by_id_value_only(client: AasHttpClient, shared_sm: model.Submodel):
1496 if client.submodels is None:
1497 pytest.skip("Submodels API is not available in this client")
1498
1499 sm_id = SM_ID
1500
1501 if client.encoded_ids:
1502 sm_id = encoder.encode_base_64(SM_ID)
1503
1504 response = client.submodels.get_submodel_by_id_value_only(sm_id)
1505
1506 parsed = urlparse(client.base_url)
1507 if parsed.port in PYTHON_SERVER_PORTS:
1508 # NOTE: python server do not provide this endpoint
1509 assert response is None
1510 return
1511 elif parsed.port in DOTNET_SERVER_PORTS:
1512 assert response is not None
1513 value = response[shared_sm.id_short]
1514 else:
1515 assert response is not None
1516 value = response
1517
1518 assert value is not None
1519 assert len(value) > 5
1520 assert "sme_property_int" in value
1521 assert int(value["sme_property_int"]) == 263
1522 assert "sme_property_string" in value
1523 assert value["sme_property_string"] == "Sample String Value"
1524 assert "sme_property_float" in value
1525 assert float(value["sme_property_float"]) == 262.1
1526
1527def test_035_patch_submodel_by_id_value_only(client: AasHttpClient, shared_sm: model.Submodel, shared_sme_string: model.Property, shared_sme_int: model.Property, shared_sme_float: model.Property):
1528 if client.submodels is None:
1529 pytest.skip("Submodels API is not available in this client")
1530
1531 sm_id = SM_ID
1532
1533 if client.encoded_ids:
1534 sm_id = encoder.encode_base_64(SM_ID)
1535
1536 value_dict = {
1537 shared_sme_string.id_short: shared_sme_string.value,
1538 shared_sme_int.id_short: str(shared_sme_int.value),
1539 shared_sme_float.id_short: str(shared_sme_float.value)
1540 }
1541
1542 # patch_dict = {shared_sm.id: value_dict}
1543
1544 patch_dict = value_dict
1545
1546 parsed = urlparse(client.base_url)
1547 if parsed.port in PYTHON_SERVER_PORTS:
1548 # NOTE: python server do not provide this endpoint
1549 return
1550
1551 if parsed.port in JAVA_SERVER_PORTS:
1552 # NOTE: java server endpoint seems to work not correctly
1553 return
1554
1555 elif parsed.port in DOTNET_SERVER_PORTS:
1556 patch_dict = value_dict
1557
1558 result = client.submodels.patch_submodel_by_id_value_only(sm_id, patch_dict)
1559
1560 assert result is True
1561
1562 string_prop_dict = client.submodels.get_submodel_element_by_path_submodel_repo(sm_id, shared_sme_string.id_short)
1563 int_prop_dict = client.submodels.get_submodel_element_by_path_submodel_repo(sm_id, shared_sme_int.id_short)
1564 float_prop_dict = client.submodels.get_submodel_element_by_path_submodel_repo(sm_id, shared_sme_float.id_short)
1565
1566 assert string_prop_dict is not None
1567 assert int_prop_dict is not None
1568 assert float_prop_dict is not None
1569
1570 assert string_prop_dict.get("value", "") == shared_sme_string.value
1571 assert int(int_prop_dict.get("value", "")) == int(shared_sme_int.value)
1572 assert float(float_prop_dict.get("value", "")) == float(shared_sme_float.value)
1573
1574
1575def test_036_get_submodel_by_id_metadata(client: AasHttpClient, shared_sm: model.Submodel):
1576 if client.submodels is None:
1577 pytest.skip("Submodels API is not available in this client")
1578
1579 sm_id = SM_ID
1580
1581 if client.encoded_ids:
1582 sm_id = encoder.encode_base_64(SM_ID)
1583
1584 metadata = client.submodels.get_submodel_by_id_metadata(sm_id)
1585 assert metadata is not None
1586
1587 submodel = client.submodels.get_submodel_by_id(sm_id)
1588 assert submodel is not None
1589
1590 assert metadata.get("id", "") == submodel.get("id", "")
1591 assert metadata.get("idShort", "") == submodel.get("idShort", "")
1592 assert metadata.get("description", {})[0].get("text", "") == submodel.get("description", {})[0].get("text", "")
1593 if "displayName" in submodel and submodel.get("displayName", []):
1594 assert metadata.get("displayName", {})[0].get("text", "") == submodel.get("displayName", {})[0].get("text", "")
1595 assert "submodelElements" not in metadata
1596
1598 if client.shells is None:
1599 pytest.skip("Shells API is not available in this client")
1600
1601 shell_id = SHELL_ID
1602
1603 if client.encoded_ids:
1604 shell_id = encoder.encode_base_64(SHELL_ID)
1605
1606 result = client.shells.delete_asset_administration_shell_by_id(shell_id)
1607
1608 assert result is True
1609
1610 get_result = client.shells.get_all_asset_administration_shells()
1611 assert get_result is not None
1612 shells = get_result.get("result", [])
1613 assert len(shells) == 0
1614
1615def test_099a_delete_submodel_by_id(client: AasHttpClient):
1616 if client.submodels is None:
1617 pytest.skip("Submodels API is not available in this client")
1618
1619 sm_id = SM_ID
1620
1621 if client.encoded_ids:
1622 sm_id = encoder.encode_base_64(SM_ID)
1623
1624 result = client.submodels.delete_submodel_by_id(sm_id)
1625
1626 assert result is True
1627
1628 get_result = client.submodels.get_all_submodels()
1629 assert get_result is not None
1630 submodels = get_result.get("result", [])
1631 assert len(submodels) == 1
1632
1633def test_099b_delete_submodel_by_id(client: AasHttpClient):
1634 if client.submodels is None:
1635 pytest.skip("Submodels API is not available in this client")
1636
1637 sm_id = AIMC_SM_ID
1638
1639 if client.encoded_ids:
1640 sm_id = encoder.encode_base_64(AIMC_SM_ID)
1641
1642 result = client.submodels.delete_submodel_by_id(sm_id)
1643
1644 assert result is True
1645
1646 get_result = client.submodels.get_all_submodels()
1647 assert get_result is not None
1648 submodels = get_result.get("result", [])
1649 assert len(submodels) == 0
test_099b_delete_submodel_by_id(AasHttpClient client)
model.SubmodelElementCollection shared_sme_collection()
test_032_put_submodel_element_by_path_submodel_repo(AasHttpClient client, model.Property shared_sme_string)
test_018b_patch_submodel_element_by_path_value_only_submodel_repo(AasHttpClient client, model.Property shared_sme_bool)
model.Property shared_sme_float()
test_028a_put_thumbnail_aas_repository_stream(AasHttpClient client)
test_013_put_submodel_by_id_aas_repository(AasHttpClient client, model.Submodel shared_sm)
test_033b_get_submodel_element_by_path_value_only_submodel_repo(AasHttpClient client, model.Property shared_sme_int)
test_018a_patch_submodel_element_by_path_value_only_submodel_repo(AasHttpClient client, model.Property shared_sme_string)
test_018d_patch_submodel_element_by_path_value_only_submodel_repo(AasHttpClient client, model.Property shared_sme_float)
test_016b_post_submodel_element_submodel_repo(AasHttpClient client, model.Property shared_sme_bool)
test_005a_put_asset_administration_shell_by_id(AasHttpClient client, model.AssetAdministrationShell shared_aas)
test_033d_get_submodel_element_by_path_value_only_submodel_repo(AasHttpClient client, model.Property shared_sme_bool)
test_000b_create_client_by_dict(AasHttpClient client)
model.Submodel shared_sm()
test_029_get_all_submodel_references_aas_repository(AasHttpClient client)
test_026_put_thumbnail_aas_repository(AasHttpClient client)
test_014_put_submodels_by_id(AasHttpClient client, model.Submodel shared_sm)
test_036_get_submodel_by_id_metadata(AasHttpClient client, model.Submodel shared_sm)
test_000a_create_client_by_url(AasHttpClient client)
test_011a_get_submodel_by_id(AasHttpClient client, model.Submodel shared_sm)
test_017d_get_submodel_element_by_path_submodel_repo(AasHttpClient client, model.Property shared_sme_float)
test_021_post_file_by_path_submodel_repo(AasHttpClient client)
test_019b_post_submodel_element_by_path_submodel_repo(AasHttpClient client)
test_007_get_submodel_by_id_aas_repository(AasHttpClient client)
test_016c_post_submodel_element_submodel_repo(AasHttpClient client, model.Property shared_sme_int)
model.AssetAdministrationShell shared_aas(model.Submodel shared_sm)
test_009a_post_submodel(AasHttpClient client, model.Submodel shared_sm)
test_033a_get_submodel_element_by_path_value_only_submodel_repo(AasHttpClient client, model.Property shared_sme_string)
model.Property shared_sme_string()
test_010_get_submodel_by_id_aas_repository(AasHttpClient client, model.Submodel shared_sm)
test_098_delete_asset_administration_shell_by_id(AasHttpClient client)
test_027_get_thumbnail_aas_repository(AasHttpClient client)
test_009b_post_submodel(AasHttpClient client)
test_002_get_all_asset_administration_shells(AasHttpClient client)
test_011d_get_submodel_by_id(AasHttpClient client)
test_024_delete_file_content_by_path_submodel_repo(AasHttpClient client)
test_015_get_all_submodel_elements_submodel_repository(AasHttpClient client, model.Submodel shared_sm)
test_011c_get_submodel_by_id(AasHttpClient client)
test_012_patch_submodel_by_id(AasHttpClient client, model.Submodel shared_sm)
test_001a_connect(AasHttpClient client)
test_017a_get_submodel_element_by_path_submodel_repo(AasHttpClient client, model.Property shared_sme_string)
test_001c_delete_all_submodels(AasHttpClient client)
test_017c_get_submodel_element_by_path_submodel_repo(AasHttpClient client, model.Property shared_sme_int)
model.Property shared_sme_int()
test_016a_post_submodel_element_submodel_repo(AasHttpClient client, model.Property shared_sme_string)
test_099a_delete_submodel_by_id(AasHttpClient client)
test_005b_put_asset_administration_shell_by_id(AasHttpClient client, model.AssetAdministrationShell shared_aas)
model.Property shared_sme_bool()
test_001b_delete_all_asset_administration_shells(AasHttpClient client)
test_006_get_asset_administration_shell_by_id_reference_aas_repository(AasHttpClient client)
test_031_delete_submodel_reference_by_id_aas_repository(AasHttpClient client)
test_030_post_submodel_reference_aas_repository(AasHttpClient client)
test_004b_get_asset_administration_shell_by_id(AasHttpClient client)
test_035_patch_submodel_by_id_value_only(AasHttpClient client, model.Submodel shared_sm, model.Property shared_sme_string, model.Property shared_sme_int, model.Property shared_sme_float)
test_022_get_file_content_by_path_submodel_repo(AasHttpClient client)
test_018c_patch_submodel_element_by_path_value_only_submodel_repo(AasHttpClient client, model.Property shared_sme_int)
test_025_get_thumbnail_aas_repository(AasHttpClient client)
test_008_get_all_submodels(AasHttpClient client)
test_011b_get_submodel_by_id(AasHttpClient client)
test_017b_get_submodel_element_by_path_submodel_repo(AasHttpClient client, model.Property shared_sme_bool)
test_003_post_asset_administration_shell(AasHttpClient client, model.AssetAdministrationShell shared_aas)
test_019a_post_submodel_element_by_path_submodel_repo(AasHttpClient client)
test_023_put_file_content_by_path_submodel_repo(AasHttpClient client)
test_004a_get_asset_administration_shell_by_id(AasHttpClient client, model.AssetAdministrationShell shared_aas)
test_028_delete_thumbnail_aas_repository(AasHttpClient client)
test_020b_encoded_ids(AasHttpClient client)
test_033c_get_submodel_element_by_path_value_only_submodel_repo(AasHttpClient client, model.Property shared_sme_float)
test_016d_post_submodel_element_submodel_repo(AasHttpClient client, model.Property shared_sme_float)
test_034_get_submodel_by_id_value_only(AasHttpClient client, model.Submodel shared_sm)