aas-http-client 1.2.20__tar.gz → 1.3.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. {aas_http_client-1.2.20 → aas_http_client-1.3.0}/PKG-INFO +1 -1
  2. {aas_http_client-1.2.20 → aas_http_client-1.3.0}/aas_http_client/classes/client/implementations/experimental_implementation.py +97 -1
  3. {aas_http_client-1.2.20 → aas_http_client-1.3.0}/aas_http_client/classes/wrapper/sdk_wrapper.py +36 -0
  4. {aas_http_client-1.2.20 → aas_http_client-1.3.0}/aas_http_client.egg-info/PKG-INFO +1 -1
  5. {aas_http_client-1.2.20 → aas_http_client-1.3.0}/pyproject.toml +1 -1
  6. {aas_http_client-1.2.20 → aas_http_client-1.3.0}/LICENSE +0 -0
  7. {aas_http_client-1.2.20 → aas_http_client-1.3.0}/README.md +0 -0
  8. {aas_http_client-1.2.20 → aas_http_client-1.3.0}/aas_http_client/__init__.py +0 -0
  9. {aas_http_client-1.2.20 → aas_http_client-1.3.0}/aas_http_client/classes/Configuration/config_classes.py +0 -0
  10. {aas_http_client-1.2.20 → aas_http_client-1.3.0}/aas_http_client/classes/client/aas_client.py +0 -0
  11. {aas_http_client-1.2.20 → aas_http_client-1.3.0}/aas_http_client/classes/client/implementations/__init__.py +0 -0
  12. {aas_http_client-1.2.20 → aas_http_client-1.3.0}/aas_http_client/classes/client/implementations/authentication.py +0 -0
  13. {aas_http_client-1.2.20 → aas_http_client-1.3.0}/aas_http_client/classes/client/implementations/shell_implementation.py +0 -0
  14. {aas_http_client-1.2.20 → aas_http_client-1.3.0}/aas_http_client/classes/client/implementations/shell_registry_implementation.py +0 -0
  15. {aas_http_client-1.2.20 → aas_http_client-1.3.0}/aas_http_client/classes/client/implementations/sm_implementation.py +0 -0
  16. {aas_http_client-1.2.20 → aas_http_client-1.3.0}/aas_http_client/classes/client/implementations/sm_registry_implementation.py +0 -0
  17. {aas_http_client-1.2.20 → aas_http_client-1.3.0}/aas_http_client/classes/wrapper/attachment.py +0 -0
  18. {aas_http_client-1.2.20 → aas_http_client-1.3.0}/aas_http_client/classes/wrapper/pagination.py +0 -0
  19. {aas_http_client-1.2.20 → aas_http_client-1.3.0}/aas_http_client/demo/demo_process.py +0 -0
  20. {aas_http_client-1.2.20 → aas_http_client-1.3.0}/aas_http_client/demo/logging_handler.py +0 -0
  21. {aas_http_client-1.2.20 → aas_http_client-1.3.0}/aas_http_client/utilities/__init__.py +0 -0
  22. {aas_http_client-1.2.20 → aas_http_client-1.3.0}/aas_http_client/utilities/constants.py +0 -0
  23. {aas_http_client-1.2.20 → aas_http_client-1.3.0}/aas_http_client/utilities/encoder.py +0 -0
  24. {aas_http_client-1.2.20 → aas_http_client-1.3.0}/aas_http_client/utilities/http_helper.py +0 -0
  25. {aas_http_client-1.2.20 → aas_http_client-1.3.0}/aas_http_client/utilities/model_builder.py +0 -0
  26. {aas_http_client-1.2.20 → aas_http_client-1.3.0}/aas_http_client/utilities/sdk_tools.py +0 -0
  27. {aas_http_client-1.2.20 → aas_http_client-1.3.0}/aas_http_client/utilities/version_check.py +0 -0
  28. {aas_http_client-1.2.20 → aas_http_client-1.3.0}/aas_http_client.egg-info/SOURCES.txt +0 -0
  29. {aas_http_client-1.2.20 → aas_http_client-1.3.0}/aas_http_client.egg-info/dependency_links.txt +0 -0
  30. {aas_http_client-1.2.20 → aas_http_client-1.3.0}/aas_http_client.egg-info/requires.txt +0 -0
  31. {aas_http_client-1.2.20 → aas_http_client-1.3.0}/aas_http_client.egg-info/top_level.txt +0 -0
  32. {aas_http_client-1.2.20 → aas_http_client-1.3.0}/setup.cfg +0 -0
  33. {aas_http_client-1.2.20 → aas_http_client-1.3.0}/tests/test_client.py +0 -0
  34. {aas_http_client-1.2.20 → aas_http_client-1.3.0}/tests/test_client_reg.py +0 -0
  35. {aas_http_client-1.2.20 → aas_http_client-1.3.0}/tests/test_sdk_tools.py +0 -0
  36. {aas_http_client-1.2.20 → aas_http_client-1.3.0}/tests/test_utils.py +0 -0
  37. {aas_http_client-1.2.20 → aas_http_client-1.3.0}/tests/test_wrapper.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aas-http-client
3
- Version: 1.2.20
3
+ Version: 1.3.0
4
4
  Summary: Flexible Python HTTP client for communication with various types of AAS servers.
5
5
  Author-email: Daniel Klein <daniel.klein@em.ag>
6
6
  License: MIT License
@@ -3,7 +3,7 @@
3
3
  import logging
4
4
  import mimetypes
5
5
  from pathlib import Path
6
- from typing import TYPE_CHECKING
6
+ from typing import TYPE_CHECKING, Any
7
7
 
8
8
  from aas_http_client.utilities.constants import LogIntensity
9
9
 
@@ -263,6 +263,54 @@ class ExperimentalImplementation(BaseModel):
263
263
 
264
264
  return True
265
265
 
266
+ # POST /submodels/{submodelIdentifier}/submodel-elements/{idShortPath}/attachment
267
+ def post_file_by_path_submodel_repo_stream(
268
+ self, submodel_identifier: str, id_short_path: str, file_octet_stream: Any, mime_type: str = "application/octet-stream"
269
+ ) -> bool:
270
+ """Uploads file content to an existing submodel element at a specified path within submodel elements hierarchy. Experimental feature - may not be supported by all servers.
271
+
272
+ :param submodel_identifier: The Submodels unique id
273
+ :param id_short_path: IdShort path to the submodel element (dot-separated)
274
+ :param file_octet_stream: File content as a byte stream
275
+ :return: Attachment data as bytes or None if an error occurred
276
+ """
277
+ if file_octet_stream is None:
278
+ _logger.error("Attachment file stream is None.")
279
+ return False
280
+
281
+ if not self._client.encoded_ids:
282
+ submodel_identifier = encode_base_64(submodel_identifier)
283
+
284
+ url = f"{self._client.base_url}/submodels/{submodel_identifier}/submodel-elements/{id_short_path}/attachment"
285
+
286
+ self._client.set_token()
287
+
288
+ try:
289
+ files = {"file": ("attachment", file_octet_stream, mime_type or "application/octet-stream")}
290
+ response = self._session.post(url, files=files, timeout=self._client.time_out)
291
+
292
+ _logger.debug(f"Call REST API url '{response.url}'")
293
+
294
+ if response.status_code == STATUS_CODE_404:
295
+ if self._client.get_log_intensity() == LogIntensity.HIGH:
296
+ _logger.warning(f"Submodel with id '{submodel_identifier}' or Submodel element with IDShort path '{id_short_path}' not found.")
297
+ elif self._client.get_log_intensity() == LogIntensity.STANDARD:
298
+ _logger.debug(f"Submodel with id '{submodel_identifier}' or Submodel element with IDShort path '{id_short_path}' not found.")
299
+
300
+ _logger.debug(response.text)
301
+ return False
302
+
303
+ # original dotnet server delivers 200 instead of 204
304
+ if response.status_code not in (STATUS_CODE_200, STATUS_CODE_204):
305
+ log_response(response)
306
+ return False
307
+
308
+ except requests.exceptions.RequestException as e:
309
+ _logger.error(f"Error call REST API: {e}")
310
+ return False
311
+
312
+ return True
313
+
266
314
  # PUT /submodels/{submodelIdentifier}/submodel-elements/{idShortPath}/attachment
267
315
  def put_file_by_path_submodel_repo(self, submodel_identifier: str, id_short_path: str, file: Path) -> bool:
268
316
  """Uploads file content to an existing submodel element at a specified path within submodel elements hierarchy. Experimental feature - may not be supported by all servers.
@@ -312,6 +360,54 @@ class ExperimentalImplementation(BaseModel):
312
360
 
313
361
  return True
314
362
 
363
+ # PUT /submodels/{submodelIdentifier}/submodel-elements/{idShortPath}/attachment
364
+ def put_file_by_path_submodel_repo_stream(
365
+ self, submodel_identifier: str, id_short_path: str, file_octet_stream: Any, mime_type: str = "application/octet-stream"
366
+ ) -> bool:
367
+ """Uploads file content to an existing submodel element at a specified path within submodel elements hierarchy. Experimental feature - may not be supported by all servers.
368
+
369
+ :param submodel_identifier: The Submodels unique id
370
+ :param id_short_path: IdShort path to the submodel element (dot-separated)
371
+ :param file_octet_stream: File content as a byte stream
372
+ :return: Attachment data as bytes or None if an error occurred
373
+ """
374
+ if file_octet_stream is None:
375
+ _logger.error("Attachment file stream is None.")
376
+ return False
377
+
378
+ if not self._client.encoded_ids:
379
+ submodel_identifier = encode_base_64(submodel_identifier)
380
+
381
+ url = f"{self._client.base_url}/submodels/{submodel_identifier}/submodel-elements/{id_short_path}/attachment"
382
+
383
+ self._client.set_token()
384
+
385
+ try:
386
+ files = {"file": ("attachment", file_octet_stream, mime_type or "application/octet-stream")}
387
+ response = self._session.put(url, files=files, timeout=self._client.time_out)
388
+
389
+ _logger.debug(f"Call REST API url '{response.url}'")
390
+
391
+ if response.status_code == STATUS_CODE_404:
392
+ if self._client.get_log_intensity() == LogIntensity.HIGH:
393
+ _logger.warning(f"Submodel with id '{submodel_identifier}' or Submodel element with IDShort path '{id_short_path}' not found.")
394
+ elif self._client.get_log_intensity() == LogIntensity.STANDARD:
395
+ _logger.debug(f"Submodel with id '{submodel_identifier}' or Submodel element with IDShort path '{id_short_path}' not found.")
396
+
397
+ _logger.debug(response.text)
398
+ return False
399
+
400
+ # original dotnet server delivers 200 instead of 204
401
+ if response.status_code not in (STATUS_CODE_200, STATUS_CODE_204):
402
+ log_response(response)
403
+ return False
404
+
405
+ except requests.exceptions.RequestException as e:
406
+ _logger.error(f"Error call REST API: {e}")
407
+ return False
408
+
409
+ return True
410
+
315
411
  # DELETE /submodels/{submodelIdentifier}/submodel-elements/{idShortPath}/attachment
316
412
  def delete_file_by_path_submodel_repo(self, submodel_identifier: str, id_short_path: str) -> bool:
317
413
  """Deletes file content of an existing submodel element at a specified path within submodel elements hierarchy. Experimental feature - may not be supported by all servers.
@@ -851,6 +851,25 @@ class SdkWrapper:
851
851
 
852
852
  return self._client.experimental.post_file_by_path_submodel_repo(submodel_identifier, id_short_path, file)
853
853
 
854
+ # POST /submodels/{submodelIdentifier}/submodel-elements/{idShortPath}/attachment
855
+ def experimental_post_file_by_path_submodel_repo_stream(
856
+ self, submodel_identifier: str, id_short_path: str, file_octet_stream: Any, mime_type: str = "application/octet-stream"
857
+ ) -> bool:
858
+ """Uploads file content to an existing submodel element at a specified path within submodel elements hierarchy. Experimental feature - may not be supported by all servers.
859
+
860
+ :param submodel_identifier: The Submodels unique id
861
+ :param id_short_path: IdShort path to the submodel element (dot-separated)
862
+ :param file_octet_stream: File content as a byte stream
863
+ :param mime_type: MIME type of the file content, defaults to "application/octet-stream"
864
+ :return: Attachment data as bytes or None if an error occurred
865
+ """
866
+ if not self._client.experimental:
867
+ _logger.error("Experimental API is not initialized in the client. Call 'initialize()' method of the client before calling this method.")
868
+ return False
869
+
870
+ return self._client.experimental.post_file_by_path_submodel_repo_stream(submodel_identifier, id_short_path, file_octet_stream, mime_type)
871
+
872
+ # PUT /submodels/{submodelIdentifier}/submodel-elements/{idShortPath}/attachment
854
873
  def experimental_put_file_by_path_submodel_repo(self, submodel_identifier: str, id_short_path: str, file: Path) -> bool:
855
874
  """Uploads file content to an existing submodel element at a specified path within submodel elements hierarchy. Experimental feature - may not be supported by all servers.
856
875
 
@@ -865,6 +884,23 @@ class SdkWrapper:
865
884
 
866
885
  return self._client.experimental.put_file_by_path_submodel_repo(submodel_identifier, id_short_path, file)
867
886
 
887
+ # PUT /submodels/{submodelIdentifier}/submodel-elements/{idShortPath}/attachment
888
+ def experimental_put_file_by_path_submodel_repo_stream(
889
+ self, submodel_identifier: str, id_short_path: str, file_octet_stream: Any, mime_type: str = "application/octet-stream"
890
+ ) -> bool:
891
+ """Uploads file content to an existing submodel element at a specified path within submodel elements hierarchy. Experimental feature - may not be supported by all servers.
892
+
893
+ :param submodel_identifier: The Submodels unique id
894
+ :param id_short_path: IdShort path to the submodel element (dot-separated)
895
+ :param file: Path to the file to upload as attachment
896
+ :return: Attachment data as bytes or None if an error occurred
897
+ """
898
+ if not self._client.experimental:
899
+ _logger.error("Experimental API is not initialized in the client. Call 'initialize()' method of the client before calling this method.")
900
+ return False
901
+
902
+ return self._client.experimental.put_file_by_path_submodel_repo_stream(submodel_identifier, id_short_path, file_octet_stream, mime_type)
903
+
868
904
  def experimental_delete_file_by_path_submodel_repo(self, submodel_identifier: str, id_short_path: str) -> bool:
869
905
  """Deletes file content of an existing submodel element at a specified path within submodel elements hierarchy. Experimental feature - may not be supported by all servers.
870
906
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aas-http-client
3
- Version: 1.2.20
3
+ Version: 1.3.0
4
4
  Summary: Flexible Python HTTP client for communication with various types of AAS servers.
5
5
  Author-email: Daniel Klein <daniel.klein@em.ag>
6
6
  License: MIT License
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "aas-http-client"
7
- version = "1.2.20"
7
+ version = "1.3.0"
8
8
  description = "Flexible Python HTTP client for communication with various types of AAS servers."
9
9
  readme = "README.md"
10
10
  license = { file = "LICENSE" }