pyxecm 1.5__py3-none-any.whl → 1.6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of pyxecm might be problematic. Click here for more details.

pyxecm/coreshare.py CHANGED
@@ -1,6 +1,7 @@
1
1
  """
2
2
  CoreShare Module to interact with the Core Share API
3
3
  See: https://confluence.opentext.com/pages/viewpage.action?spaceKey=OTC&title=APIs+Consumption+based+on+roles
4
+ See also: https://swagger.otxlab.net/ui/?branch=master&yaml=application-specific/core/core-api.yaml
4
5
 
5
6
  Authentication - get Client Secrets:
6
7
  1. Login to Core Share as a Tenant Admin User .
@@ -16,7 +17,12 @@ __init__ : class initializer
16
17
  config : Returns config data set
17
18
  credentials: Get credentials (username + password)
18
19
  set_credentials: Set the credentials for Core Share based on username and password.
19
- request_header: Returns the request header for Core Share API calls
20
+
21
+ request_header_admin: Returns the request header used for Application calls
22
+ that require administrator credentials
23
+ request_header_user: Returns the request header used for Application calls
24
+ that require user (non-admin) credentials.
25
+ do_request: call an Core Share REST API in a safe way.
20
26
  parse_request_response: Parse the REST API responses and convert
21
27
  them to Python dict in a safe way
22
28
  lookup_result_value: Lookup a property value based on a provided key / value pair in the response
@@ -71,8 +77,10 @@ __email__ = "mdiefenb@opentext.com"
71
77
  import os
72
78
  import json
73
79
  import logging
74
- import urllib.parse
80
+ import time
75
81
 
82
+ import urllib.parse
83
+ from http import HTTPStatus
76
84
  import requests
77
85
 
78
86
  logger = logging.getLogger("pyxecm.customizer.coreshare")
@@ -83,6 +91,8 @@ REQUEST_LOGIN_HEADERS = {
83
91
  }
84
92
 
85
93
  REQUEST_TIMEOUT = 60
94
+ REQUEST_RETRY_DELAY = 20
95
+ REQUEST_MAX_RETRIES = 2
86
96
 
87
97
 
88
98
  class CoreShare(object):
@@ -248,7 +258,8 @@ class CoreShare(object):
248
258
  # end method definition
249
259
 
250
260
  def request_header_admin(self, content_type: str = "application/json") -> dict:
251
- """Returns the request header used for Application calls.
261
+ """Returns the request header used for Application calls
262
+ that require administrator credentials.
252
263
  Consists of Bearer access token and Content Type
253
264
 
254
265
  Args:
@@ -268,7 +279,8 @@ class CoreShare(object):
268
279
  # end method definition
269
280
 
270
281
  def request_header_user(self, content_type: str = "application/json") -> dict:
271
- """Returns the request header used for Application calls.
282
+ """Returns the request header used for Application calls
283
+ that require user (non-admin) credentials.
272
284
  Consists of Bearer access token and Content Type
273
285
 
274
286
  Args:
@@ -287,6 +299,186 @@ class CoreShare(object):
287
299
 
288
300
  # end method definition
289
301
 
302
+ def do_request(
303
+ self,
304
+ url: str,
305
+ method: str = "GET",
306
+ headers: dict | None = None,
307
+ data: dict | None = None,
308
+ json_data: dict | None = None,
309
+ files: dict | None = None,
310
+ timeout: int | None = REQUEST_TIMEOUT,
311
+ show_error: bool = True,
312
+ show_warning: bool = False,
313
+ warning_message: str = "",
314
+ failure_message: str = "",
315
+ success_message: str = "",
316
+ max_retries: int = REQUEST_MAX_RETRIES,
317
+ retry_forever: bool = False,
318
+ parse_request_response: bool = True,
319
+ user_credentials: bool = False,
320
+ verify: bool = True,
321
+ ) -> dict | None:
322
+ """Call an OTDS REST API in a safe way
323
+
324
+ Args:
325
+ url (str): URL to send the request to.
326
+ method (str, optional): HTTP method (GET, POST, etc.). Defaults to "GET".
327
+ headers (dict | None, optional): Request Headers. Defaults to None.
328
+ data (dict | None, optional): Request payload. Defaults to None
329
+ files (dict | None, optional): Dictionary of {"name": file-tuple} for multipart encoding upload.
330
+ file-tuple can be a 2-tuple ("filename", fileobj) or a 3-tuple ("filename", fileobj, "content_type")
331
+ timeout (int | None, optional): Timeout for the request in seconds. Defaults to REQUEST_TIMEOUT.
332
+ show_error (bool, optional): Whether or not an error should be logged in case of a failed REST call.
333
+ If False, then only a warning is logged. Defaults to True.
334
+ warning_message (str, optional): Specific warning message. Defaults to "". If not given the error_message will be used.
335
+ failure_message (str, optional): Specific error message. Defaults to "".
336
+ success_message (str, optional): Specific success message. Defaults to "".
337
+ max_retries (int, optional): How many retries on Connection errors? Default is REQUEST_MAX_RETRIES.
338
+ retry_forever (bool, optional): Eventually wait forever - without timeout. Defaults to False.
339
+ parse_request_response (bool, optional): should the response.text be interpreted as json and loaded into a dictionary. True is the default.
340
+ user_credentials (bool, optional): defines if admin or user credentials are used for the REST API call. Default = False = admin credentials
341
+ verify (bool, optional): specify whether or not SSL certificates should be verified when making an HTTPS request. Default = True
342
+
343
+ Returns:
344
+ dict | None: Response of OTDS REST API or None in case of an error.
345
+ """
346
+
347
+ if headers is None:
348
+ logger.error("Missing request header. Cannot send request to Core Share!")
349
+ return None
350
+
351
+ # In case of an expired session we reauthenticate and
352
+ # try 1 more time. Session expiration should not happen
353
+ # twice in a row:
354
+ retries = 0
355
+
356
+ while True:
357
+ try:
358
+ response = requests.request(
359
+ method=method,
360
+ url=url,
361
+ data=data,
362
+ json=json_data,
363
+ files=files,
364
+ headers=headers,
365
+ timeout=timeout,
366
+ verify=verify,
367
+ )
368
+
369
+ if response.ok:
370
+ if success_message:
371
+ logger.info(success_message)
372
+ if parse_request_response:
373
+ return self.parse_request_response(response)
374
+ else:
375
+ return response
376
+ # Check if Session has expired - then re-authenticate and try once more
377
+ elif response.status_code == 401 and retries == 0:
378
+ if user_credentials:
379
+ logger.debug(
380
+ "User session has expired - try to re-authenticate..."
381
+ )
382
+ self.authenticate_user(revalidate=True)
383
+ # Make sure to not change the content type:
384
+ headers = self.request_header_user(
385
+ content_type=headers.get("Content-Type", None)
386
+ )
387
+ else:
388
+ logger.warning(
389
+ "Admin session has expired - try to re-authenticate..."
390
+ )
391
+ self.authenticate_admin(revalidate=True)
392
+ # Make sure to not change the content type:
393
+ headers = self.request_header_admin(
394
+ content_type=headers.get("Content-Type", None)
395
+ )
396
+ retries += 1
397
+ else:
398
+ # Handle plain HTML responses to not pollute the logs
399
+ content_type = response.headers.get("content-type", None)
400
+ if content_type == "text/html":
401
+ response_text = "HTML content (only printed in debug log)"
402
+ elif "image" in content_type:
403
+ response_text = "Image content (not printed)"
404
+ else:
405
+ response_text = response.text
406
+
407
+ if show_error:
408
+ logger.error(
409
+ "%s; status -> %s/%s; error -> %s",
410
+ failure_message,
411
+ response.status_code,
412
+ HTTPStatus(response.status_code).phrase,
413
+ response_text,
414
+ )
415
+ elif show_warning:
416
+ logger.warning(
417
+ "%s; status -> %s/%s; warning -> %s",
418
+ warning_message if warning_message else failure_message,
419
+ response.status_code,
420
+ HTTPStatus(response.status_code).phrase,
421
+ response_text,
422
+ )
423
+ if content_type == "text/html":
424
+ logger.debug(
425
+ "%s; status -> %s/%s; warning -> %s",
426
+ failure_message,
427
+ response.status_code,
428
+ HTTPStatus(response.status_code).phrase,
429
+ response.text,
430
+ )
431
+ return None
432
+ except requests.exceptions.Timeout:
433
+ if retries <= max_retries:
434
+ logger.warning(
435
+ "Request timed out. Retrying in %s seconds...",
436
+ str(REQUEST_RETRY_DELAY),
437
+ )
438
+ retries += 1
439
+ time.sleep(REQUEST_RETRY_DELAY) # Add a delay before retrying
440
+ else:
441
+ logger.error(
442
+ "%s; timeout error",
443
+ failure_message,
444
+ )
445
+ if retry_forever:
446
+ # If it fails after REQUEST_MAX_RETRIES retries we let it wait forever
447
+ logger.warning("Turn timeouts off and wait forever...")
448
+ timeout = None
449
+ else:
450
+ return None
451
+ except requests.exceptions.ConnectionError:
452
+ if retries <= max_retries:
453
+ logger.warning(
454
+ "Connection error. Retrying in %s seconds...",
455
+ str(REQUEST_RETRY_DELAY),
456
+ )
457
+ retries += 1
458
+ time.sleep(REQUEST_RETRY_DELAY) # Add a delay before retrying
459
+ else:
460
+ logger.error(
461
+ "%s; connection error",
462
+ failure_message,
463
+ )
464
+ if retry_forever:
465
+ # If it fails after REQUEST_MAX_RETRIES retries we let it wait forever
466
+ logger.warning("Turn timeouts off and wait forever...")
467
+ timeout = None
468
+ time.sleep(REQUEST_RETRY_DELAY) # Add a delay before retrying
469
+ else:
470
+ return None
471
+ # end try
472
+ logger.debug(
473
+ "Retrying REST API %s call -> %s... (retry = %s)",
474
+ method,
475
+ url,
476
+ str(retries),
477
+ )
478
+ # end while True
479
+
480
+ # end method definition
481
+
290
482
  def parse_request_response(
291
483
  self,
292
484
  response_object: requests.Response,
@@ -652,25 +844,14 @@ class CoreShare(object):
652
844
 
653
845
  logger.debug("Get Core Share groups; calling -> %s", request_url)
654
846
 
655
- retries = 0
656
- while True:
657
- response = requests.get(
658
- request_url, headers=request_header, timeout=REQUEST_TIMEOUT
659
- )
660
- if response.ok:
661
- return self.parse_request_response(response)
662
- elif response.status_code == 401 and retries == 0:
663
- logger.debug("Session has expired - try to re-authenticate...")
664
- self.authenticate_user(revalidate=True)
665
- request_header = self.request_header_user()
666
- retries += 1
667
- else:
668
- logger.error(
669
- "Failed to get Core Share groups; status -> %s; error -> %s",
670
- response.status_code,
671
- response.text,
672
- )
673
- return None
847
+ return self.do_request(
848
+ url=request_url,
849
+ method="GET",
850
+ headers=request_header,
851
+ timeout=REQUEST_TIMEOUT,
852
+ failure_message="Failed to get Core Share groups",
853
+ user_credentials=True,
854
+ )
674
855
 
675
856
  # end method definition
676
857
 
@@ -720,29 +901,15 @@ class CoreShare(object):
720
901
  "Adding Core Share group -> %s; calling -> %s", group_name, request_url
721
902
  )
722
903
 
723
- retries = 0
724
- while True:
725
- response = requests.post(
726
- request_url,
727
- headers=request_header,
728
- data=json.dumps(payload),
729
- timeout=REQUEST_TIMEOUT,
730
- )
731
- if response.ok:
732
- return self.parse_request_response(response)
733
- elif response.status_code == 401 and retries == 0:
734
- logger.debug("Session has expired - try to re-authenticate...")
735
- self.authenticate_admin(revalidate=True)
736
- request_header = self.request_header_admin()
737
- retries += 1
738
- else:
739
- logger.error(
740
- "Failed to add Core Share group -> %s; status -> %s; error -> %s",
741
- group_name,
742
- response.status_code,
743
- response.text,
744
- )
745
- return None
904
+ return self.do_request(
905
+ url=request_url,
906
+ method="POST",
907
+ headers=request_header,
908
+ data=json.dumps(payload),
909
+ timeout=REQUEST_TIMEOUT,
910
+ failure_message="Failed to add Core Share group -> '{}'".format(group_name),
911
+ user_credentials=False,
912
+ )
746
913
 
747
914
  # end method definition
748
915
 
@@ -787,35 +954,25 @@ class CoreShare(object):
787
954
  if not self._access_token_admin:
788
955
  self.authenticate_admin()
789
956
 
790
- request_header = self.request_header_user()
957
+ request_header = self.request_header_admin()
791
958
  request_url = self.config()["groupsUrl"] + "/{}".format(group_id) + "/members"
792
959
 
793
960
  logger.debug(
794
- "Get members for Core Share group -> %s; calling -> %s",
961
+ "Get members for Core Share group with ID -> %s; calling -> %s",
795
962
  group_id,
796
963
  request_url,
797
964
  )
798
965
 
799
- retries = 0
800
- while True:
801
- response = requests.get(
802
- request_url, headers=request_header, timeout=REQUEST_TIMEOUT
803
- )
804
- if response.ok:
805
- return self.parse_request_response(response)
806
- elif response.status_code == 401 and retries == 0:
807
- logger.debug("Session has expired - try to re-authenticate...")
808
- self.authenticate_admin(revalidate=True)
809
- request_header = self.request_header_admin()
810
- retries += 1
811
- else:
812
- logger.error(
813
- "Failed to get members of Core Share group -> %s; status -> %s; error -> %s",
814
- group_id,
815
- response.status_code,
816
- response.text,
817
- )
818
- return None
966
+ return self.do_request(
967
+ url=request_url,
968
+ method="GET",
969
+ headers=request_header,
970
+ timeout=REQUEST_TIMEOUT,
971
+ failure_message="Failed to get members of Core Share group -> '{}'".format(
972
+ group_id
973
+ ),
974
+ user_credentials=False,
975
+ )
819
976
 
820
977
  # end method definition
821
978
 
@@ -868,7 +1025,7 @@ class CoreShare(object):
868
1025
  if not self._access_token_admin:
869
1026
  self.authenticate_admin()
870
1027
 
871
- request_header = self.request_header_user()
1028
+ request_header = self.request_header_admin()
872
1029
  request_url = self.config()["groupsUrl"] + "/{}".format(group_id) + "/members"
873
1030
 
874
1031
  user = self.get_user_by_id(user_id=user_id)
@@ -877,7 +1034,7 @@ class CoreShare(object):
877
1034
  payload = {"members": [user_email], "specificGroupRole": is_group_admin}
878
1035
 
879
1036
  logger.debug(
880
- "Add Core Share user -> %s (%s) as %s to Core Share group -> %s; calling -> %s",
1037
+ "Add Core Share user -> '%s' (%s) as %s to Core Share group with ID -> %s; calling -> %s",
881
1038
  user_email,
882
1039
  user_id,
883
1040
  "group member" if not is_group_admin else "group admin",
@@ -885,30 +1042,17 @@ class CoreShare(object):
885
1042
  request_url,
886
1043
  )
887
1044
 
888
- retries = 0
889
- while True:
890
- response = requests.post(
891
- request_url,
892
- headers=request_header,
893
- json=payload,
894
- timeout=REQUEST_TIMEOUT,
895
- )
896
- if response.ok:
897
- return self.parse_request_response(response)
898
- elif response.status_code == 401 and retries == 0:
899
- logger.debug("Session has expired - try to re-authenticate...")
900
- self.authenticate_admin(revalidate=True)
901
- request_header = self.request_header_admin()
902
- retries += 1
903
- else:
904
- logger.error(
905
- "Failed to add Core Share user -> %s to Core Share group -> %s; status -> %s; error -> %s",
906
- user_id,
907
- group_id,
908
- response.status_code,
909
- response.text,
910
- )
911
- return None
1045
+ return self.do_request(
1046
+ url=request_url,
1047
+ method="POST",
1048
+ headers=request_header,
1049
+ json_data=payload,
1050
+ timeout=REQUEST_TIMEOUT,
1051
+ failure_message="Failed to add Core Share user -> '{}' to Core Share group with ID -> {}".format(
1052
+ user_email, group_id
1053
+ ),
1054
+ user_credentials=False,
1055
+ )
912
1056
 
913
1057
  # end method definition
914
1058
 
@@ -939,10 +1083,10 @@ class CoreShare(object):
939
1083
  ]
940
1084
  """
941
1085
 
942
- if not self._access_token_user:
943
- self.authenticate_user()
1086
+ if not self._access_token_admin:
1087
+ self.authenticate_admin()
944
1088
 
945
- request_header = self.request_header_user()
1089
+ request_header = self.request_header_admin()
946
1090
  request_url = self.config()["groupsUrl"] + "/{}".format(group_id) + "/members"
947
1091
 
948
1092
  user = self.get_user_by_id(user_id=user_id)
@@ -951,7 +1095,7 @@ class CoreShare(object):
951
1095
  payload = {"members": [user_email], "specificGroupRole": is_group_admin}
952
1096
 
953
1097
  logger.debug(
954
- "Remove Core Share user -> %s (%s) as %s from Core Share group -> %s; calling -> %s",
1098
+ "Remove Core Share user -> '%s' (%s) as %s from Core Share group with ID -> %s; calling -> %s",
955
1099
  user_email,
956
1100
  user_id,
957
1101
  "group member" if not is_group_admin else "group admin",
@@ -959,30 +1103,17 @@ class CoreShare(object):
959
1103
  request_url,
960
1104
  )
961
1105
 
962
- retries = 0
963
- while True:
964
- response = requests.delete(
965
- request_url,
966
- headers=request_header,
967
- json=payload,
968
- timeout=REQUEST_TIMEOUT,
969
- )
970
- if response.ok:
971
- return self.parse_request_response(response)
972
- elif response.status_code == 401 and retries == 0:
973
- logger.debug("Session has expired - try to re-authenticate...")
974
- self.authenticate_user(revalidate=True)
975
- request_header = self.request_header_user()
976
- retries += 1
977
- else:
978
- logger.error(
979
- "Failed to remove Core Share user -> %s from Core Share group -> %s; status -> %s; error -> %s",
980
- user_id,
981
- group_id,
982
- response.status_code,
983
- response.text,
984
- )
985
- return None
1106
+ return self.do_request(
1107
+ url=request_url,
1108
+ method="DELETE",
1109
+ headers=request_header,
1110
+ json_data=payload,
1111
+ timeout=REQUEST_TIMEOUT,
1112
+ failure_message="Failed to remove Core Share user -> '{}' ({}) from Core Share group with ID -> {}".format(
1113
+ user_email, user_id, group_id
1114
+ ),
1115
+ user_credentials=False,
1116
+ )
986
1117
 
987
1118
  # end method definition
988
1119
 
@@ -998,36 +1129,26 @@ class CoreShare(object):
998
1129
  Response example:
999
1130
  """
1000
1131
 
1001
- if not self._access_token_user:
1002
- self.authenticate_user()
1132
+ if not self._access_token_admin:
1133
+ self.authenticate_admin()
1003
1134
 
1004
- request_header = self.request_header_user()
1135
+ request_header = self.request_header_admin()
1005
1136
  request_url = self.config()["groupsUrl"] + "/" + group_id
1006
1137
 
1007
1138
  logger.debug(
1008
1139
  "Get Core Share group with ID -> %s; calling -> %s", group_id, request_url
1009
1140
  )
1010
1141
 
1011
- retries = 0
1012
- while True:
1013
- response = requests.get(
1014
- request_url, headers=request_header, timeout=REQUEST_TIMEOUT
1015
- )
1016
- if response.ok:
1017
- return self.parse_request_response(response)
1018
- elif response.status_code == 401 and retries == 0:
1019
- logger.debug("Session has expired - try to re-authenticate...")
1020
- self.authenticate_user(revalidate=True)
1021
- request_header = self.request_header_user()
1022
- retries += 1
1023
- else:
1024
- logger.error(
1025
- "Failed to get Core Share group with ID -> %s; status -> %s; error -> %s",
1026
- group_id,
1027
- response.status_code,
1028
- response.text,
1029
- )
1030
- return None
1142
+ return self.do_request(
1143
+ url=request_url,
1144
+ method="GET",
1145
+ headers=request_header,
1146
+ timeout=REQUEST_TIMEOUT,
1147
+ failure_message="Failed to get Core Share group with ID -> {}".format(
1148
+ group_id
1149
+ ),
1150
+ user_credentials=False,
1151
+ )
1031
1152
 
1032
1153
  # end method definition
1033
1154
 
@@ -1092,26 +1213,16 @@ class CoreShare(object):
1092
1213
  "Search Core Share group by -> %s; calling -> %s", query_string, request_url
1093
1214
  )
1094
1215
 
1095
- retries = 0
1096
- while True:
1097
- response = requests.get(
1098
- request_url, headers=request_header, timeout=REQUEST_TIMEOUT
1099
- )
1100
- if response.ok:
1101
- return self.parse_request_response(response)
1102
- elif response.status_code == 401 and retries == 0:
1103
- logger.debug("Session has expired - try to re-authenticate...")
1104
- self.authenticate_admin(revalidate=True)
1105
- request_header = self.request_header_admin()
1106
- retries += 1
1107
- else:
1108
- logger.error(
1109
- "Cannot find Core Share group with name / property -> %s; status -> %s; error -> %s",
1110
- query_string,
1111
- response.status_code,
1112
- response.text,
1113
- )
1114
- return None
1216
+ return self.do_request(
1217
+ url=request_url,
1218
+ method="GET",
1219
+ headers=request_header,
1220
+ timeout=REQUEST_TIMEOUT,
1221
+ failure_message="Cannot find Core Share group with name / property -> {}".format(
1222
+ query_string
1223
+ ),
1224
+ user_credentials=False,
1225
+ )
1115
1226
 
1116
1227
  # end method definition
1117
1228
 
@@ -1197,25 +1308,14 @@ class CoreShare(object):
1197
1308
 
1198
1309
  logger.debug("Get Core Share users; calling -> %s", request_url)
1199
1310
 
1200
- retries = 0
1201
- while True:
1202
- response = requests.get(
1203
- request_url, headers=request_header, timeout=REQUEST_TIMEOUT
1204
- )
1205
- if response.ok:
1206
- return self.parse_request_response(response)
1207
- elif response.status_code == 401 and retries == 0:
1208
- logger.debug("Session has expired - try to re-authenticate...")
1209
- self.authenticate_admin(revalidate=True)
1210
- request_header = self.request_header_admin()
1211
- retries += 1
1212
- else:
1213
- logger.error(
1214
- "Failed to get Core Share users; status -> %s; error -> %s",
1215
- response.status_code,
1216
- response.text,
1217
- )
1218
- return None
1311
+ return self.do_request(
1312
+ url=request_url,
1313
+ method="GET",
1314
+ headers=request_header,
1315
+ timeout=REQUEST_TIMEOUT,
1316
+ failure_message="Failed to get Core Share users",
1317
+ user_credentials=False,
1318
+ )
1219
1319
 
1220
1320
  # end method definition
1221
1321
 
@@ -1299,26 +1399,16 @@ class CoreShare(object):
1299
1399
  "Get Core Share user with ID -> %s; calling -> %s", user_id, request_url
1300
1400
  )
1301
1401
 
1302
- retries = 0
1303
- while True:
1304
- response = requests.get(
1305
- request_url, headers=request_header, timeout=REQUEST_TIMEOUT
1306
- )
1307
- if response.ok:
1308
- return self.parse_request_response(response)
1309
- elif response.status_code == 401 and retries == 0:
1310
- logger.debug("Session has expired - try to re-authenticate...")
1311
- self.authenticate_user(revalidate=True)
1312
- request_header = self.request_header_user()
1313
- retries += 1
1314
- else:
1315
- logger.error(
1316
- "Failed to get Core Share user with ID -> %s; status -> %s; error -> %s",
1317
- user_id,
1318
- response.status_code,
1319
- response.text,
1320
- )
1321
- return None
1402
+ return self.do_request(
1403
+ url=request_url,
1404
+ method="GET",
1405
+ headers=request_header,
1406
+ timeout=REQUEST_TIMEOUT,
1407
+ failure_message="Failed to get Core Share user with ID -> {}".format(
1408
+ user_id
1409
+ ),
1410
+ user_credentials=True,
1411
+ )
1322
1412
 
1323
1413
  # end method definition
1324
1414
 
@@ -1453,26 +1543,16 @@ class CoreShare(object):
1453
1543
  "Search Core Share user by -> %s; calling -> %s", query_string, request_url
1454
1544
  )
1455
1545
 
1456
- retries = 0
1457
- while True:
1458
- response = requests.get(
1459
- request_url, headers=request_header, timeout=REQUEST_TIMEOUT
1460
- )
1461
- if response.ok:
1462
- return self.parse_request_response(response)
1463
- elif response.status_code == 401 and retries == 0:
1464
- logger.debug("Session has expired - try to re-authenticate...")
1465
- self.authenticate_admin(revalidate=True)
1466
- request_header = self.request_header_admin()
1467
- retries += 1
1468
- else:
1469
- logger.error(
1470
- "Failed to search Core Share user with name / property -> %s; status -> %s; error -> %s",
1471
- query_string,
1472
- response.status_code,
1473
- response.text,
1474
- )
1475
- return None
1546
+ return self.do_request(
1547
+ url=request_url,
1548
+ method="GET",
1549
+ headers=request_header,
1550
+ timeout=REQUEST_TIMEOUT,
1551
+ failure_message="Failed to search Core Share user with name / property -> {}".format(
1552
+ query_string
1553
+ ),
1554
+ user_credentials=False,
1555
+ )
1476
1556
 
1477
1557
  # end method definition
1478
1558
 
@@ -1564,31 +1644,17 @@ class CoreShare(object):
1564
1644
  request_url,
1565
1645
  )
1566
1646
 
1567
- retries = 0
1568
- while True:
1569
- response = requests.post(
1570
- request_url,
1571
- headers=request_header,
1572
- json=payload,
1573
- timeout=REQUEST_TIMEOUT,
1574
- )
1575
- if response.ok:
1576
- return self.parse_request_response(response)
1577
- elif response.status_code == 401 and retries == 0:
1578
- logger.debug("Session has expired - try to re-authenticate...")
1579
- self.authenticate_admin(revalidate=True)
1580
- request_header = self.request_header_admin()
1581
- retries += 1
1582
- else:
1583
- logger.error(
1584
- "Failed to add Core Share user -> %s %s (%s); status -> %s; error -> %s",
1585
- first_name,
1586
- last_name,
1587
- email,
1588
- response.status_code,
1589
- response.text,
1590
- )
1591
- return None
1647
+ return self.do_request(
1648
+ url=request_url,
1649
+ method="POST",
1650
+ headers=request_header,
1651
+ json_data=payload,
1652
+ timeout=REQUEST_TIMEOUT,
1653
+ failure_message="Failed to add Core Share user -> '{} {}' ({})".format(
1654
+ first_name, last_name, email
1655
+ ),
1656
+ user_credentials=False,
1657
+ )
1592
1658
 
1593
1659
  # end method definition
1594
1660
 
@@ -1617,29 +1683,17 @@ class CoreShare(object):
1617
1683
 
1618
1684
  update_data = {"resend": True}
1619
1685
 
1620
- retries = 0
1621
- while True:
1622
- response = requests.put(
1623
- request_url,
1624
- json=update_data,
1625
- headers=request_header,
1626
- timeout=REQUEST_TIMEOUT,
1627
- )
1628
- if response.ok:
1629
- return self.parse_request_response(response)
1630
- elif response.status_code == 401 and retries == 0:
1631
- logger.debug("Admin Session has expired - try to re-authenticate...")
1632
- self.authenticate_admin(revalidate=True)
1633
- request_header = self.request_header_admin()
1634
- retries += 1
1635
- else:
1636
- logger.error(
1637
- "Failed to resend invite for Core Share user -> %s; status -> %s; error -> %s",
1638
- user_id,
1639
- response.status_code,
1640
- response.text,
1641
- )
1642
- return None
1686
+ return self.do_request(
1687
+ url=request_url,
1688
+ method="PUT",
1689
+ headers=request_header,
1690
+ json_data=update_data,
1691
+ timeout=REQUEST_TIMEOUT,
1692
+ failure_message="Failed to resend invite for Core Share user with ID -> {}".format(
1693
+ user_id
1694
+ ),
1695
+ user_credentials=False,
1696
+ )
1643
1697
 
1644
1698
  # end method definition
1645
1699
 
@@ -1671,29 +1725,17 @@ class CoreShare(object):
1671
1725
  "Trying to update the email without providing the password. This is likely to fail..."
1672
1726
  )
1673
1727
 
1674
- retries = 0
1675
- while True:
1676
- response = requests.put(
1677
- request_url,
1678
- json=update_data,
1679
- headers=request_header,
1680
- timeout=REQUEST_TIMEOUT,
1681
- )
1682
- if response.ok:
1683
- return self.parse_request_response(response)
1684
- elif response.status_code == 401 and retries == 0:
1685
- logger.debug("Admin Session has expired - try to re-authenticate...")
1686
- self.authenticate_admin(revalidate=True)
1687
- request_header = self.request_header_admin()
1688
- retries += 1
1689
- else:
1690
- logger.error(
1691
- "Failed to update Core Share user -> %s; status -> %s; error -> %s",
1692
- user_id,
1693
- response.status_code,
1694
- response.text,
1695
- )
1696
- return None
1728
+ return self.do_request(
1729
+ url=request_url,
1730
+ method="PUT",
1731
+ headers=request_header,
1732
+ json_data=update_data,
1733
+ timeout=REQUEST_TIMEOUT,
1734
+ failure_message="Failed to update Core Share user with ID -> {}".format(
1735
+ user_id
1736
+ ),
1737
+ user_credentials=False,
1738
+ )
1697
1739
 
1698
1740
  # end method definition
1699
1741
 
@@ -1729,30 +1771,16 @@ class CoreShare(object):
1729
1771
  request_url,
1730
1772
  )
1731
1773
 
1732
- retries = 0
1733
- while True:
1734
- response = requests.put(
1735
- request_url,
1736
- # json=update_data,
1737
- headers=request_header,
1738
- timeout=REQUEST_TIMEOUT,
1739
- )
1740
- if response.ok:
1741
- return self.parse_request_response(response)
1742
- elif response.status_code == 401 and retries == 0:
1743
- logger.debug("Admin Session has expired - try to re-authenticate...")
1744
- self.authenticate_admin(revalidate=True)
1745
- request_header = self.request_header_admin()
1746
- retries += 1
1747
- else:
1748
- logger.error(
1749
- "Failed to add access role -> %s to Core Share user -> %s; status -> %s; error -> %s",
1750
- str(role_id),
1751
- user_id,
1752
- response.status_code,
1753
- response.text,
1754
- )
1755
- return None
1774
+ return self.do_request(
1775
+ url=request_url,
1776
+ method="PUT",
1777
+ headers=request_header,
1778
+ timeout=REQUEST_TIMEOUT,
1779
+ failure_message="Failed to add access role with ID -> {} to Core Share user with ID -> {}".format(
1780
+ role_id, user_id
1781
+ ),
1782
+ user_credentials=False,
1783
+ )
1756
1784
 
1757
1785
  # end method definition
1758
1786
 
@@ -1782,36 +1810,22 @@ class CoreShare(object):
1782
1810
  )
1783
1811
 
1784
1812
  logger.debug(
1785
- "Remove access role -> %s from Core Share user with ID -> %s; calling -> %s",
1813
+ "Remove access role with ID -> %s from Core Share user with ID -> %s; calling -> %s",
1786
1814
  str(role_id),
1787
1815
  user_id,
1788
1816
  request_url,
1789
1817
  )
1790
1818
 
1791
- retries = 0
1792
- while True:
1793
- response = requests.delete(
1794
- request_url,
1795
- # json=update_data,
1796
- headers=request_header,
1797
- timeout=REQUEST_TIMEOUT,
1798
- )
1799
- if response.ok:
1800
- return self.parse_request_response(response)
1801
- elif response.status_code == 401 and retries == 0:
1802
- logger.debug("Admin Session has expired - try to re-authenticate...")
1803
- self.authenticate_admin(revalidate=True)
1804
- request_header = self.request_header_admin()
1805
- retries += 1
1806
- else:
1807
- logger.error(
1808
- "Failed to remove access role -> %s from Core Share user -> %s; status -> %s; error -> %s",
1809
- str(role_id),
1810
- user_id,
1811
- response.status_code,
1812
- response.text,
1813
- )
1814
- return None
1819
+ return self.do_request(
1820
+ url=request_url,
1821
+ method="DELETE",
1822
+ headers=request_header,
1823
+ timeout=REQUEST_TIMEOUT,
1824
+ failure_message="Failed to remove access role with ID -> {} from Core Share user with ID -> {}".format(
1825
+ role_id, user_id
1826
+ ),
1827
+ user_credentials=False,
1828
+ )
1815
1829
 
1816
1830
  # end method definition
1817
1831
 
@@ -1908,36 +1922,22 @@ class CoreShare(object):
1908
1922
 
1909
1923
  update_data = {"password": password, "newpassword": new_password}
1910
1924
 
1911
- retries = 0
1912
- while True:
1913
- response = requests.put(
1914
- request_url,
1915
- json=update_data,
1916
- headers=request_header,
1917
- timeout=REQUEST_TIMEOUT,
1918
- )
1919
- if response.ok:
1920
- return self.parse_request_response(response)
1921
- elif response.status_code == 401 and retries == 0:
1922
- logger.debug("Admin Session has expired - try to re-authenticate...")
1923
- self.authenticate_admin(revalidate=True)
1924
- request_header = self.request_header_admin()
1925
- retries += 1
1926
- else:
1927
- logger.error(
1928
- "Failed to update password of Core Share user -> %s; status -> %s; error -> %s",
1929
- user_id,
1930
- response.status_code,
1931
- response.text,
1932
- )
1933
- return None
1925
+ return self.do_request(
1926
+ url=request_url,
1927
+ method="PUT",
1928
+ headers=request_header,
1929
+ json_data=update_data,
1930
+ timeout=REQUEST_TIMEOUT,
1931
+ failure_message="Failed to update password of Core Share user with ID -> {}".format(
1932
+ user_id
1933
+ ),
1934
+ user_credentials=False,
1935
+ )
1934
1936
 
1935
1937
  # end method definition
1936
1938
 
1937
1939
  def update_user_photo(
1938
- self,
1939
- user_id: str,
1940
- photo_path: str,
1940
+ self, user_id: str, photo_path: str, mime_type: str = "image/jpeg"
1941
1941
  ) -> dict | None:
1942
1942
  """Update the Core Share user photo.
1943
1943
 
@@ -1969,7 +1969,7 @@ class CoreShare(object):
1969
1969
 
1970
1970
  request_url = self.config()["usersUrlv3"] + "/{}".format(user_id) + "/photo"
1971
1971
  files = {
1972
- "file": (photo_path, photo_data, "image/jpeg"),
1972
+ "file": (photo_path, photo_data, mime_type),
1973
1973
  }
1974
1974
 
1975
1975
  logger.debug(
@@ -1978,29 +1978,18 @@ class CoreShare(object):
1978
1978
  request_url,
1979
1979
  )
1980
1980
 
1981
- retries = 0
1982
- while True:
1983
- response = requests.post(
1984
- request_url,
1985
- files=files,
1986
- headers=self.request_header_user(content_type=""),
1987
- verify=False,
1988
- timeout=REQUEST_TIMEOUT,
1989
- )
1990
- if response.ok:
1991
- return self.parse_request_response(response)
1992
- elif response.status_code == 401 and retries == 0:
1993
- logger.debug("Session has expired - try to re-authenticate...")
1994
- self.authenticate_user(revalidate=True)
1995
- retries += 1
1996
- else:
1997
- logger.error(
1998
- "Failed to update profile photo of Core Share user with ID -> %s; status -> %s; error -> %s",
1999
- user_id,
2000
- response.status_code,
2001
- response.text,
2002
- )
2003
- return None
1981
+ return self.do_request(
1982
+ url=request_url,
1983
+ method="POST",
1984
+ headers=self.request_header_user(content_type=""),
1985
+ files=files,
1986
+ timeout=REQUEST_TIMEOUT,
1987
+ failure_message="Failed to update profile photo of Core Share user with ID -> {}".format(
1988
+ user_id
1989
+ ),
1990
+ user_credentials=True,
1991
+ verify=False,
1992
+ )
2004
1993
 
2005
1994
  # end method definition
2006
1995
 
@@ -2084,26 +2073,16 @@ class CoreShare(object):
2084
2073
  request_url,
2085
2074
  )
2086
2075
 
2087
- retries = 0
2088
- while True:
2089
- response = requests.get(
2090
- request_url, headers=request_header, timeout=REQUEST_TIMEOUT
2091
- )
2092
- if response.ok:
2093
- return self.parse_request_response(response)
2094
- elif response.status_code == 401 and retries == 0:
2095
- logger.debug("Session has expired - try to re-authenticate...")
2096
- self.authenticate_user(revalidate=True)
2097
- request_header = self.request_header_user()
2098
- retries += 1
2099
- else:
2100
- logger.error(
2101
- "Failed to get Core Share folders under parent -> %s; status -> %s; error -> %s",
2102
- parent_id,
2103
- response.status_code,
2104
- response.text,
2105
- )
2106
- return None
2076
+ return self.do_request(
2077
+ url=request_url,
2078
+ method="GET",
2079
+ headers=request_header,
2080
+ timeout=REQUEST_TIMEOUT,
2081
+ failure_message="Failed to get Core Share folders under parent -> {}".format(
2082
+ parent_id
2083
+ ),
2084
+ user_credentials=True,
2085
+ )
2107
2086
 
2108
2087
  # end method definition
2109
2088
 
@@ -2133,26 +2112,16 @@ class CoreShare(object):
2133
2112
  request_url,
2134
2113
  )
2135
2114
 
2136
- retries = 0
2137
- while True:
2138
- response = requests.delete(
2139
- request_url, headers=request_header, timeout=REQUEST_TIMEOUT
2140
- )
2141
- if response.ok:
2142
- return self.parse_request_response(response)
2143
- elif response.status_code == 401 and retries == 0:
2144
- logger.debug("Session has expired - try to re-authenticate...")
2145
- self.authenticate_user(revalidate=True)
2146
- request_header = self.request_header_user()
2147
- retries += 1
2148
- else:
2149
- logger.error(
2150
- "Failed to unshare Core Share folder -> %s; status -> %s; error -> %s",
2151
- resource_id,
2152
- response.status_code,
2153
- response.text,
2154
- )
2155
- return None
2115
+ return self.do_request(
2116
+ url=request_url,
2117
+ method="DELETE",
2118
+ headers=request_header,
2119
+ timeout=REQUEST_TIMEOUT,
2120
+ failure_message="Failed to unshare Core Share folder with ID -> {}".format(
2121
+ resource_id
2122
+ ),
2123
+ user_credentials=True,
2124
+ )
2156
2125
 
2157
2126
  # end method definition
2158
2127
 
@@ -2182,29 +2151,17 @@ class CoreShare(object):
2182
2151
  request_url,
2183
2152
  )
2184
2153
 
2185
- retries = 0
2186
- while True:
2187
- response = requests.put(
2188
- request_url,
2189
- headers=request_header,
2190
- data=json.dumps(payload),
2191
- timeout=REQUEST_TIMEOUT,
2192
- )
2193
- if response.ok:
2194
- return self.parse_request_response(response)
2195
- elif response.status_code == 401 and retries == 0:
2196
- logger.debug("Session has expired - try to re-authenticate...")
2197
- self.authenticate_user(revalidate=True)
2198
- request_header = self.request_header_user()
2199
- retries += 1
2200
- else:
2201
- logger.error(
2202
- "Failed to delete Core Share folder -> %s; status -> %s; error -> %s",
2203
- resource_id,
2204
- response.status_code,
2205
- response.text,
2206
- )
2207
- return None
2154
+ return self.do_request(
2155
+ url=request_url,
2156
+ method="PUT",
2157
+ headers=request_header,
2158
+ data=json.dumps(payload),
2159
+ timeout=REQUEST_TIMEOUT,
2160
+ failure_message="Failed to delete Core Share folder -> {}".format(
2161
+ resource_id
2162
+ ),
2163
+ user_credentials=True,
2164
+ )
2208
2165
 
2209
2166
  # end method definition
2210
2167
 
@@ -2234,29 +2191,17 @@ class CoreShare(object):
2234
2191
  request_url,
2235
2192
  )
2236
2193
 
2237
- retries = 0
2238
- while True:
2239
- response = requests.put(
2240
- request_url,
2241
- headers=request_header,
2242
- data=json.dumps(payload),
2243
- timeout=REQUEST_TIMEOUT,
2244
- )
2245
- if response.ok:
2246
- return self.parse_request_response(response)
2247
- elif response.status_code == 401 and retries == 0:
2248
- logger.debug("Session has expired - try to re-authenticate...")
2249
- self.authenticate_user(revalidate=True)
2250
- request_header = self.request_header_user()
2251
- retries += 1
2252
- else:
2253
- logger.error(
2254
- "Failed to delete Core Share document -> %s; status -> %s; error -> %s",
2255
- resource_id,
2256
- response.status_code,
2257
- response.text,
2258
- )
2259
- return None
2194
+ return self.do_request(
2195
+ url=request_url,
2196
+ method="PUT",
2197
+ headers=request_header,
2198
+ data=json.dumps(payload),
2199
+ timeout=REQUEST_TIMEOUT,
2200
+ failure_message="Failed to delete Core Share document -> {}".format(
2201
+ resource_id
2202
+ ),
2203
+ user_credentials=True,
2204
+ )
2260
2205
 
2261
2206
  # end method definition
2262
2207
 
@@ -2286,35 +2231,23 @@ class CoreShare(object):
2286
2231
  payload = {"action": "LEAVE_SHARE"}
2287
2232
 
2288
2233
  logger.debug(
2289
- "User -> %s leaves Core Share shared folder -> %s; calling -> %s",
2234
+ "User with ID -> %s leaves Core Share shared folder with ID -> %s; calling -> %s",
2290
2235
  user_id,
2291
2236
  resource_id,
2292
2237
  request_url,
2293
2238
  )
2294
2239
 
2295
- retries = 0
2296
- while True:
2297
- response = requests.delete(
2298
- request_url,
2299
- headers=request_header,
2300
- data=json.dumps(payload),
2301
- timeout=REQUEST_TIMEOUT,
2302
- )
2303
- if response.ok:
2304
- return self.parse_request_response(response)
2305
- elif response.status_code == 401 and retries == 0:
2306
- logger.debug("Session has expired - try to re-authenticate...")
2307
- self.authenticate_user(revalidate=True)
2308
- request_header = self.request_header_user()
2309
- retries += 1
2310
- else:
2311
- logger.error(
2312
- "Failed to leave Core Share folder -> %s; status -> %s; error -> %s",
2313
- resource_id,
2314
- response.status_code,
2315
- response.text,
2316
- )
2317
- return None
2240
+ return self.do_request(
2241
+ url=request_url,
2242
+ method="DELETE",
2243
+ headers=request_header,
2244
+ data=json.dumps(payload),
2245
+ timeout=REQUEST_TIMEOUT,
2246
+ failure_message="User with ID -> {} failed to leave Core Share folder with ID -> {}".format(
2247
+ user_id, resource_id
2248
+ ),
2249
+ user_credentials=True,
2250
+ )
2318
2251
 
2319
2252
  # end method definition
2320
2253
 
@@ -2345,28 +2278,16 @@ class CoreShare(object):
2345
2278
  request_url,
2346
2279
  )
2347
2280
 
2348
- retries = 0
2349
- while True:
2350
- response = requests.delete(
2351
- request_url,
2352
- headers=request_header,
2353
- timeout=REQUEST_TIMEOUT,
2354
- )
2355
- if response.ok:
2356
- return self.parse_request_response(response)
2357
- elif response.status_code == 401 and retries == 0:
2358
- logger.debug("Session has expired - try to re-authenticate...")
2359
- self.authenticate_user(revalidate=True)
2360
- request_header = self.request_header_user()
2361
- retries += 1
2362
- else:
2363
- logger.error(
2364
- "Failed to stop sharing Core Share folder -> %s; status -> %s; error -> %s",
2365
- resource_id,
2366
- response.status_code,
2367
- response.text,
2368
- )
2369
- return None
2281
+ return self.do_request(
2282
+ url=request_url,
2283
+ method="DELETE",
2284
+ headers=request_header,
2285
+ timeout=REQUEST_TIMEOUT,
2286
+ failure_message="User with ID -> {} failed to stop sharing Core Share folder with ID -> {}".format(
2287
+ user_id, resource_id
2288
+ ),
2289
+ user_credentials=True,
2290
+ )
2370
2291
 
2371
2292
  # end method definition
2372
2293
 
@@ -2517,28 +2438,16 @@ class CoreShare(object):
2517
2438
  request_url,
2518
2439
  )
2519
2440
 
2520
- retries = 0
2521
- while True:
2522
- response = requests.get(
2523
- request_url,
2524
- headers=request_header,
2525
- timeout=REQUEST_TIMEOUT,
2526
- )
2527
- if response.ok:
2528
- return self.parse_request_response(response)
2529
- elif response.status_code == 401 and retries == 0:
2530
- logger.debug("Session has expired - try to re-authenticate...")
2531
- self.authenticate_admin(revalidate=True)
2532
- request_header = self.request_header_admin()
2533
- retries += 1
2534
- else:
2535
- logger.error(
2536
- "Failed to get shares of Core Share group -> %s; status -> %s; error -> %s",
2537
- group_id,
2538
- response.status_code,
2539
- response.text,
2540
- )
2541
- return None
2441
+ return self.do_request(
2442
+ url=request_url,
2443
+ method="GET",
2444
+ headers=request_header,
2445
+ timeout=REQUEST_TIMEOUT,
2446
+ failure_message="Failed to get shares of Core Share group -> {}".format(
2447
+ group_id
2448
+ ),
2449
+ user_credentials=False,
2450
+ )
2542
2451
 
2543
2452
  # end method definition
2544
2453
 
@@ -2572,29 +2481,16 @@ class CoreShare(object):
2572
2481
  request_url,
2573
2482
  )
2574
2483
 
2575
- retries = 0
2576
- while True:
2577
- response = requests.delete(
2578
- request_url,
2579
- headers=request_header,
2580
- timeout=REQUEST_TIMEOUT,
2581
- )
2582
- if response.ok:
2583
- return self.parse_request_response(response)
2584
- elif response.status_code == 401 and retries == 0:
2585
- logger.debug("Session has expired - try to re-authenticate...")
2586
- self.authenticate_admin(revalidate=True)
2587
- request_header = self.request_header_admin()
2588
- retries += 1
2589
- else:
2590
- logger.error(
2591
- "Failed to revoke sharing Core Share folder -> %s with group -> %s; status -> %s; error -> %s",
2592
- resource_id,
2593
- group_id,
2594
- response.status_code,
2595
- response.text,
2596
- )
2597
- return None
2484
+ return self.do_request(
2485
+ url=request_url,
2486
+ method="DELETE",
2487
+ headers=request_header,
2488
+ timeout=REQUEST_TIMEOUT,
2489
+ failure_message="Failed to revoke sharing Core Share folder with ID -> {} with group with ID -> {}".format(
2490
+ resource_id, group_id
2491
+ ),
2492
+ user_credentials=False,
2493
+ )
2598
2494
 
2599
2495
  # end method definition
2600
2496