1"""Implementation of Asset Administration Shell related API calls."""
6from pathlib
import Path
7from typing
import TYPE_CHECKING, Any
10from pydantic
import BaseModel
13 from aas_http_client.classes.client.aas_client
import AasHttpClient
25_logger = logging.getLogger(__name__)
29 """Implementation of Asset Administration Shell related API calls."""
31 def __init__(self, client:
"AasHttpClient"):
32 """Initializes the ShellImplementation with the given parameters."""
35 session = client.get_session()
38 "HTTP session is not initialized in the client. Call 'initialize()' method of the client before creating ShellRepoImplementation instance."
41 self._session: requests.Session = session
45 """Returns a specific Asset Administration Shell.
47 :param aas_identifier: The Asset Administration Shells unique id
48 :return: Asset Administration Shells data or None if an error occurred
50 if not self.
_client.encoded_ids:
51 aas_identifier = encode_base_64(aas_identifier)
53 url = f
"{self._client.base_url}/shells/{aas_identifier}"
58 response = self._session.get(url, timeout=self.
_client.time_out)
59 _logger.debug(f
"Call REST API url '{response.url}'")
61 if response.status_code == STATUS_CODE_404:
62 if self.
_client.get_log_intensity() == LogIntensity.HIGH:
63 _logger.warning(f
"Asset Administration Shell with id '{aas_identifier}' not found.")
64 elif self.
_client.get_log_intensity() == LogIntensity.STANDARD:
65 _logger.debug(f
"Asset Administration Shell with id '{aas_identifier}' not found.")
67 _logger.debug(response.text)
70 if response.status_code != STATUS_CODE_200:
71 log_response(response)
74 except requests.exceptions.RequestException
as e:
75 _logger.error(f
"Error call REST API: {e}")
78 content = response.content.decode(
"utf-8")
79 return json.loads(content)
83 """Creates or replaces an existing Asset Administration Shell.
85 :param aas_identifier: The Asset Administration Shells unique id
86 :param request_body: Json data of the Asset Administration Shell data to put
87 :return: True if the update was successful, False otherwise
89 if not self.
_client.encoded_ids:
90 aas_identifier = encode_base_64(aas_identifier)
92 url = f
"{self._client.base_url}/shells/{aas_identifier}"
97 response = self._session.put(url, json=request_body, timeout=self.
_client.time_out)
98 _logger.debug(f
"Call REST API url '{response.url}'")
100 if response.status_code == STATUS_CODE_404:
101 if self.
_client.get_log_intensity() == LogIntensity.HIGH:
102 _logger.warning(f
"Asset Administration Shell with id '{aas_identifier}' not found.")
103 elif self.
_client.get_log_intensity() == LogIntensity.STANDARD:
104 _logger.debug(f
"Asset Administration Shell with id '{aas_identifier}' not found.")
106 _logger.debug(response.text)
109 if response.status_code != STATUS_CODE_204:
110 log_response(response)
113 except requests.exceptions.RequestException
as e:
114 _logger.error(f
"Error call REST API: {e}")
121 """Deletes an Asset Administration Shell.
123 :param aas_identifier: The Asset Administration Shells unique id
124 :return: True if the deletion was successful, False otherwise
126 if not self.
_client.encoded_ids:
127 aas_identifier = encode_base_64(aas_identifier)
129 url = f
"{self._client.base_url}/shells/{aas_identifier}"
134 response = self._session.delete(url, timeout=self.
_client.time_out)
135 _logger.debug(f
"Call REST API url '{response.url}'")
137 if response.status_code == STATUS_CODE_404:
138 if self.
_client.get_log_intensity() == LogIntensity.HIGH:
139 _logger.warning(f
"Asset Administration Shell with id '{aas_identifier}' not found.")
140 elif self.
_client.get_log_intensity() == LogIntensity.STANDARD:
141 _logger.debug(f
"Asset Administration Shell with id '{aas_identifier}' not found.")
143 _logger.debug(response.text)
146 if response.status_code != STATUS_CODE_204:
147 log_response(response)
150 except requests.exceptions.RequestException
as e:
151 _logger.error(f
"Error call REST API: {e}")
158 """Returns the thumbnail of the Asset Administration Shell.
160 :param aas_identifier: The Asset Administration Shells unique id
161 :return: Thumbnail file data as bytes (octet-stream) or None if an error occurred
163 if not self.
_client.encoded_ids:
164 aas_identifier = encode_base_64(aas_identifier)
166 url = f
"{self._client.base_url}/shells/{aas_identifier}/asset-information/thumbnail"
171 response = self._session.get(url, timeout=self.
_client.time_out)
172 _logger.debug(f
"Call REST API url '{response.url}'")
174 if response.status_code == STATUS_CODE_404:
175 if self.
_client.get_log_intensity() == LogIntensity.HIGH:
176 _logger.warning(f
"Asset Administration Shell with id '{aas_identifier}' or thumbnail file not found.")
177 elif self.
_client.get_log_intensity() == LogIntensity.STANDARD:
178 _logger.debug(f
"Asset Administration Shell with id '{aas_identifier}' or thumbnail file not found.")
180 _logger.debug(response.text)
183 if response.status_code != STATUS_CODE_200:
184 log_response(response)
187 except requests.exceptions.RequestException
as e:
188 _logger.error(f
"Error call REST API: {e}")
191 return response.content
194 """Creates or updates the thumbnail of the Asset Administration Shell.
196 :param aas_identifier: The Asset Administration Shells unique id
197 :param file_name: The name of the thumbnail file
198 :param file: Path to the thumbnail file to upload as attachment
199 :return: True if the update was successful, False otherwise
201 if file.exists()
is False or not file.is_file():
202 _logger.error(f
"Attachment file '{file}' does not exist.")
205 mime_type, _ = mimetypes.guess_type(file)
207 with file.open(
"rb")
as f:
208 file_octet_stream = f.read()
214 self, aas_identifier: str, file_name: str, file_octet_stream: Any, mime_type: str =
"application/octet-stream"
216 """Creates or updates the thumbnail of the Asset Administration Shell.
218 :param aas_identifier: The Asset Administration Shells unique id
219 :param file_name: The name of the thumbnail file
220 :param file_octet_stream: The octet stream of the thumbnail file
221 :param mime_type: The MIME type of the thumbnail file (e.g., "image/png")
222 :return: True if the update was successful, False otherwise
224 if file_name
is None or file_name ==
"" or file_octet_stream
is None or mime_type
is None or mime_type ==
"":
225 _logger.error(f
"Attachment file '{file_name}' does not exist.")
228 if not self.
_client.encoded_ids:
229 aas_identifier = encode_base_64(aas_identifier)
231 url = f
"{self._client.base_url}/shells/{aas_identifier}/asset-information/thumbnail"
233 params = {
"fileName": file_name}
238 files: dict[str, tuple[str, Any, str]] = {
"file": (file_name, file_octet_stream, mime_type)}
239 response = self._session.put(url, files=files, params=params, timeout=self.
_client.time_out)
241 _logger.debug(f
"Call REST API url '{response.url}'")
243 if response.status_code == STATUS_CODE_404:
244 if self.
_client.get_log_intensity() == LogIntensity.HIGH:
245 _logger.warning(f
"Asset Administration Shell with id '{aas_identifier}' not found.")
246 elif self.
_client.get_log_intensity() == LogIntensity.STANDARD:
247 _logger.debug(f
"Asset Administration Shell with id '{aas_identifier}' not found.")
249 _logger.debug(response.text)
253 if response.status_code
not in (STATUS_CODE_200, STATUS_CODE_204):
254 log_response(response)
257 except requests.exceptions.RequestException
as e:
258 _logger.error(f
"Error call REST API: {e}")
265 """Deletes the thumbnail of the Asset Administration Shell.
267 :param aas_identifier: The Asset Administration Shells unique id
268 :return: True if the deletion was successful, False otherwise
270 if not self.
_client.encoded_ids:
271 aas_identifier = encode_base_64(aas_identifier)
273 url = f
"{self._client.base_url}/shells/{aas_identifier}/asset-information/thumbnail"
278 response = self._session.delete(url, timeout=self.
_client.time_out)
279 _logger.debug(f
"Call REST API url '{response.url}'")
281 if response.status_code == STATUS_CODE_404:
282 if self.
_client.get_log_intensity() == LogIntensity.HIGH:
283 _logger.warning(f
"Asset Administration Shell with id '{aas_identifier}' or thumbnail file not found.")
284 elif self.
_client.get_log_intensity() == LogIntensity.STANDARD:
285 _logger.debug(f
"Asset Administration Shell with id '{aas_identifier}' or thumbnail file not found.")
287 _logger.debug(response.text)
290 if response.status_code != STATUS_CODE_200:
291 log_response(response)
294 except requests.exceptions.RequestException
as e:
295 _logger.error(f
"Error call REST API: {e}")
302 self, asset_ids: list[dict] |
None =
None, id_short: str =
"", limit: int = 100, cursor: str =
""
304 """Returns all Asset Administration Shells.
306 :param assetIds: A list of specific Asset identifiers (format: {"identifier": "string", "encodedIdentifier": "string"})
307 :param idShort: The Asset Administration Shells IdShort
308 :param limit: The maximum number of elements in the response array
309 :param cursor: A server-generated identifier retrieved from pagingMetadata that specifies from which position the result listing should continue
310 :return: List of paginated Asset Administration Shells data or None if an error occurred
312 url = f
"{self._client.base_url}/shells"
315 if asset_ids
is None:
318 params: dict[str, Any] = {}
319 if asset_ids
is not None and len(asset_ids) > 0:
320 params[
"assetIds"] = asset_ids
322 params[
"idShort"] = id_short
324 params[
"limit"] = str(limit)
326 params[
"cursor"] = cursor
331 response = self._session.get(url, timeout=self.
_client.time_out, params=params)
332 _logger.debug(f
"Call REST API url '{response.url}'")
334 if response.status_code != STATUS_CODE_200:
335 log_response(response)
338 except requests.exceptions.RequestException
as e:
339 _logger.error(f
"Error call REST API: {e}")
342 content = response.content.decode(
"utf-8")
343 return json.loads(content)
347 """Creates a new Asset Administration Shell.
349 :param request_body: Json data of the Asset Administration Shell to post
350 :return: Response data as a dictionary or None if an error occurred
352 url = f
"{self._client.base_url}/shells"
357 response = self._session.post(url, json=request_body, timeout=self.
_client.time_out)
358 _logger.debug(f
"Call REST API url '{response.url}'")
360 if response.status_code != STATUS_CODE_201:
361 log_response(response)
364 except requests.exceptions.RequestException
as e:
365 _logger.error(f
"Error call REST API: {e}")
368 content = response.content.decode(
"utf-8")
369 return json.loads(content)
373 """Returns all submodel references.
375 :param aas_identifier: The Asset Administration Shells unique id
376 :param limit: The maximum number of elements in the response array
377 :param cursor: A server-generated identifier retrieved from pagingMetadata that specifies from which position the result listing should continue
378 :return: List of Submodel references or None if an error occurred
380 if not self.
_client.encoded_ids:
381 aas_identifier = encode_base_64(aas_identifier)
383 url = f
"{self._client.base_url}/shells/{aas_identifier}/submodel-refs"
385 params: dict[str, str] = {}
387 params[
"limit"] = str(limit)
389 params[
"cursor"] = cursor
394 response = self._session.get(url, timeout=self.
_client.time_out, params=params)
395 _logger.debug(f
"Call REST API url '{response.url}'")
397 if response.status_code == STATUS_CODE_404:
398 if self.
_client.get_log_intensity() == LogIntensity.HIGH:
399 _logger.warning(f
"Asset Administration Shell with id '{aas_identifier}' not found.")
400 elif self.
_client.get_log_intensity() == LogIntensity.STANDARD:
401 _logger.debug(f
"Asset Administration Shell with id '{aas_identifier}' not found.")
403 _logger.debug(response.text)
406 if response.status_code != STATUS_CODE_200:
407 log_response(response)
410 except requests.exceptions.RequestException
as e:
411 _logger.error(f
"Error call REST API: {e}")
414 content = response.content.decode(
"utf-8")
415 return json.loads(content)
419 """Creates a submodel reference at the Asset Administration Shell.
421 :param aas_identifier: The Asset Administration Shells unique id
422 :param request_body: Reference to the Submodel
423 :return: Response data as a dictionary or None if an error occurred
425 if not self.
_client.encoded_ids:
426 aas_identifier = encode_base_64(aas_identifier)
428 url = f
"{self._client.base_url}/shells/{aas_identifier}/submodel-refs"
433 response = self._session.post(url, json=request_body, timeout=self.
_client.time_out)
434 _logger.debug(f
"Call REST API url '{response.url}'")
436 if response.status_code == STATUS_CODE_404:
437 if self.
_client.get_log_intensity() == LogIntensity.HIGH:
438 _logger.warning(f
"Asset Administration Shell with id '{aas_identifier}' not found.")
439 elif self.
_client.get_log_intensity() == LogIntensity.STANDARD:
440 _logger.debug(f
"Asset Administration Shell with id '{aas_identifier}' not found.")
442 _logger.debug(response.text)
445 if response.status_code != STATUS_CODE_201:
446 log_response(response)
449 except requests.exceptions.RequestException
as e:
450 _logger.error(f
"Error call REST API: {e}")
453 content = response.content.decode(
"utf-8")
454 return json.loads(content)
458 """Deletes the submodel reference from the Asset Administration Shell. Does not delete the submodel itself.
460 :param aas_identifier: The Asset Administration Shells unique id
461 :param submodel_identifier: The Submodels unique id
462 :return: True if the deletion was successful, False otherwise
464 if not self.
_client.encoded_ids:
465 aas_identifier = encode_base_64(aas_identifier)
466 submodel_identifier = encode_base_64(submodel_identifier)
468 url = f
"{self._client.base_url}/shells/{aas_identifier}/submodel-refs/{submodel_identifier}"
473 response = self._session.delete(url, timeout=self.
_client.time_out)
474 _logger.debug(f
"Call REST API url '{response.url}'")
476 if response.status_code == STATUS_CODE_404:
477 if self.
_client.get_log_intensity() == LogIntensity.HIGH:
478 _logger.warning(f
"Asset Administration Shell with id '{aas_identifier}' or submodel with id '{submodel_identifier}' not found.")
479 elif self.
_client.get_log_intensity() == LogIntensity.STANDARD:
480 _logger.debug(f
"Asset Administration Shell with id '{aas_identifier}' or submodel with id '{submodel_identifier}' not found.")
482 _logger.debug(response.text)
485 if response.status_code
not in (STATUS_CODE_204, STATUS_CODE_200):
486 log_response(response)
489 except requests.exceptions.RequestException
as e:
490 _logger.error(f
"Error call REST API: {e}")
499 """Updates the Submodel.
501 :param aas_identifier: ID of the AAS to update the submodel for
502 :param submodel_identifier: ID of the submodel to update
503 :param request_body: Json data to the Submodel to put
504 :return: True if the update was successful, False otherwise
506 if not self.
_client.encoded_ids:
507 aas_identifier = encode_base_64(aas_identifier)
508 submodel_identifier = encode_base_64(submodel_identifier)
510 url = f
"{self._client.base_url}/shells/{aas_identifier}/submodels/{submodel_identifier}"
515 response = self._session.put(url, json=request_body, timeout=self.
_client.time_out)
516 _logger.debug(f
"Call REST API url '{response.url}'")
518 if response.status_code == STATUS_CODE_404:
519 if self.
_client.get_log_intensity() == LogIntensity.HIGH:
520 _logger.warning(f
"Asset Administration Shell with id '{aas_identifier}' or submodel with id '{submodel_identifier}' not found.")
521 elif self.
_client.get_log_intensity() == LogIntensity.STANDARD:
522 _logger.debug(f
"Asset Administration Shell with id '{aas_identifier}' or submodel with id '{submodel_identifier}' not found.")
524 _logger.debug(response.text)
527 if response.status_code != STATUS_CODE_204:
528 log_response(response)
531 except requests.exceptions.RequestException
as e:
532 _logger.error(f
"Error call REST API: {e}")
539 """Returns a specific Asset Administration Shell as a Reference.
541 :param aas_identifier: ID of the AAS reference to retrieve
542 :return: Asset Administration Shells reference data or None if an error occurred
544 if not self.
_client.encoded_ids:
545 aas_identifier = encode_base_64(aas_identifier)
547 url = f
"{self._client.base_url}/shells/{aas_identifier}/$reference"
552 response = self._session.get(url, timeout=self.
_client.time_out)
553 _logger.debug(f
"Call REST API url '{response.url}'")
555 if response.status_code == STATUS_CODE_404:
556 if self.
_client.get_log_intensity() == LogIntensity.HIGH:
557 _logger.warning(f
"Asset Administration Shell with id '{aas_identifier}' not found.")
558 elif self.
_client.get_log_intensity() == LogIntensity.STANDARD:
559 _logger.debug(f
"Asset Administration Shell with id '{aas_identifier}' not found.")
561 _logger.debug(response.text)
564 if response.status_code != STATUS_CODE_200:
565 log_response(response)
568 except requests.exceptions.RequestException
as e:
569 _logger.error(f
"Error call REST API: {e}")
572 ref_dict_string = response.content.decode(
"utf-8")
573 return json.loads(ref_dict_string)
577 """Returns the Submodel.
579 :param aas_identifier: ID of the AAS to retrieve the submodel from
580 :param submodel_identifier: ID of the submodel to retrieve
581 :return: Submodel object or None if an error occurred
583 if not self.
_client.encoded_ids:
584 aas_identifier = encode_base_64(aas_identifier)
585 submodel_identifier = encode_base_64(submodel_identifier)
587 url = f
"{self._client.base_url}/shells/{aas_identifier}/submodels/{submodel_identifier}"
592 response = self._session.get(url, timeout=self.
_client.time_out)
593 _logger.debug(f
"Call REST API url '{response.url}'")
595 if response.status_code == STATUS_CODE_404:
596 if self.
_client.get_log_intensity() == LogIntensity.HIGH:
597 _logger.warning(f
"Asset Administration Shell with id '{aas_identifier}' or submodel with id '{submodel_identifier}' not found.")
598 elif self.
_client.get_log_intensity() == LogIntensity.STANDARD:
599 _logger.debug(f
"Asset Administration Shell with id '{aas_identifier}' or submodel with id '{submodel_identifier}' not found.")
601 _logger.debug(response.text)
604 if response.status_code != STATUS_CODE_200:
605 log_response(response)
608 except requests.exceptions.RequestException
as e:
609 _logger.error(f
"Error call REST API: {e}")
612 content = response.content.decode(
"utf-8")
613 return json.loads(content)
Implementation of Asset Administration Shell related API calls.
bool delete_thumbnail_aas_repository(self, str aas_identifier)
Deletes the thumbnail of the Asset Administration Shell.
dict|None post_asset_administration_shell(self, dict request_body)
Creates a new Asset Administration Shell.
dict|None get_all_submodel_references_aas_repository(self, str aas_identifier, int limit=100, str cursor="")
Returns all submodel references.
dict|None get_asset_administration_shell_by_id(self, str aas_identifier)
Returns a specific Asset Administration Shell.
__init__(self, "AasHttpClient" client)
Initializes the ShellImplementation with the given parameters.
bytes|None get_thumbnail_aas_repository(self, str aas_identifier)
Returns the thumbnail of the Asset Administration Shell.
dict|None get_asset_administration_shell_by_id_reference_aas_repository(self, str aas_identifier)
Returns a specific Asset Administration Shell as a Reference.
dict|None get_all_asset_administration_shells(self, list[dict]|None asset_ids=None, str id_short="", int limit=100, str cursor="")
Returns all Asset Administration Shells.
bool put_submodel_by_id_aas_repository(self, str aas_identifier, str submodel_identifier, dict request_body)
Updates the Submodel.
bool delete_asset_administration_shell_by_id(self, str aas_identifier)
Deletes an Asset Administration Shell.
dict|None get_submodel_by_id_aas_repository(self, str aas_identifier, str submodel_identifier)
Returns the Submodel.
bool put_thumbnail_aas_repository_stream(self, str aas_identifier, str file_name, Any file_octet_stream, str mime_type="application/octet-stream")
Creates or updates the thumbnail of the Asset Administration Shell.
dict|None post_submodel_reference_aas_repository(self, str aas_identifier, dict request_body)
Creates a submodel reference at the Asset Administration Shell.
bool delete_submodel_reference_by_id_aas_repository(self, str aas_identifier, str submodel_identifier)
Deletes the submodel reference from the Asset Administration Shell.
bool put_asset_administration_shell_by_id(self, str aas_identifier, dict request_body)
Creates or replaces an existing Asset Administration Shell.
bool put_thumbnail_aas_repository(self, str aas_identifier, str file_name, Path file)
Creates or updates the thumbnail of the Asset Administration Shell.