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