pyGuardPoint 2.0.0__tar.gz → 2.0.2__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 (67) hide show
  1. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/PKG-INFO +3 -1
  2. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/_guardpoint_cardholders.py +15 -5
  3. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/_guardpoint_customizedfields.py +34 -2
  4. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/gp_asyncio/_async_guardpoint_cardholders.py +14 -5
  5. pyguardpoint-2.0.2/pyGuardPoint/gp_asyncio/_async_guardpoint_customizedfields.py +67 -0
  6. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/guardpoint_connection.py +9 -4
  7. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/guardpoint_dataclasses.py +35 -0
  8. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint.egg-info/PKG-INFO +3 -1
  9. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/setup.py +2 -1
  10. pyguardpoint-2.0.0/pyGuardPoint/gp_asyncio/_async_guardpoint_customizedfields.py +0 -36
  11. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/LICENSE.txt +0 -0
  12. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/README.rst +0 -0
  13. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/CustomWebsocketTransport.py +0 -0
  14. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/CustomWebsocketTransportOld.py +0 -0
  15. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/__init__.py +0 -0
  16. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/_guardpoint_accessgroups.py +0 -0
  17. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/_guardpoint_alarmstates.py +0 -0
  18. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/_guardpoint_alarmzones.py +0 -0
  19. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/_guardpoint_areas.py +0 -0
  20. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/_guardpoint_cardholdertypes.py +0 -0
  21. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/_guardpoint_cards.py +0 -0
  22. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/_guardpoint_controllers.py +0 -0
  23. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/_guardpoint_departments.py +0 -0
  24. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/_guardpoint_diagnostic.py +0 -0
  25. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/_guardpoint_events.py +0 -0
  26. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/_guardpoint_genericinformation.py +0 -0
  27. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/_guardpoint_inputs.py +0 -0
  28. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/_guardpoint_manualevents.py +0 -0
  29. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/_guardpoint_ouputs.py +0 -0
  30. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/_guardpoint_personaldetails.py +0 -0
  31. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/_guardpoint_readers.py +0 -0
  32. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/_guardpoint_scheduledmags.py +0 -0
  33. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/_guardpoint_securitygroups.py +0 -0
  34. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/_guardpoint_sites.py +0 -0
  35. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/_odata_filter.py +0 -0
  36. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/_str_match_algo.py +0 -0
  37. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/gp_asyncio/__init__.py +0 -0
  38. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/gp_asyncio/_async_guardpoint_accessgroups.py +0 -0
  39. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/gp_asyncio/_async_guardpoint_alarmstates.py +0 -0
  40. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/gp_asyncio/_async_guardpoint_alarmzones.py +0 -0
  41. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/gp_asyncio/_async_guardpoint_areas.py +0 -0
  42. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/gp_asyncio/_async_guardpoint_cardholdertypes.py +0 -0
  43. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/gp_asyncio/_async_guardpoint_cards.py +0 -0
  44. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/gp_asyncio/_async_guardpoint_controllers.py +0 -0
  45. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/gp_asyncio/_async_guardpoint_departments.py +0 -0
  46. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/gp_asyncio/_async_guardpoint_diagnostic.py +0 -0
  47. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/gp_asyncio/_async_guardpoint_events.py +0 -0
  48. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/gp_asyncio/_async_guardpoint_genericinformation.py +0 -0
  49. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/gp_asyncio/_async_guardpoint_manualevents.py +0 -0
  50. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/gp_asyncio/_async_guardpoint_ouputs.py +0 -0
  51. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/gp_asyncio/_async_guardpoint_personaldetails.py +0 -0
  52. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/gp_asyncio/_async_guardpoint_readers.py +0 -0
  53. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/gp_asyncio/_async_guardpoint_scheduledmags.py +0 -0
  54. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/gp_asyncio/_async_guardpoint_securitygroups.py +0 -0
  55. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/gp_asyncio/_async_guardpoint_sites.py +0 -0
  56. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/gp_asyncio/guardpoint_connection_asyncio.py +0 -0
  57. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/guardpoint.py +0 -0
  58. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/guardpoint_asyncio.py +0 -0
  59. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/guardpoint_error.py +0 -0
  60. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/guardpoint_threaded.py +0 -0
  61. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint/guardpoint_utils.py +0 -0
  62. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint.egg-info/SOURCES.txt +0 -0
  63. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint.egg-info/dependency_links.txt +0 -0
  64. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint.egg-info/not-zip-safe +0 -0
  65. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint.egg-info/requires.txt +0 -0
  66. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/pyGuardPoint.egg-info/top_level.txt +0 -0
  67. {pyguardpoint-2.0.0 → pyguardpoint-2.0.2}/setup.cfg +0 -0
@@ -1,9 +1,10 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyGuardPoint
3
- Version: 2.0.0
3
+ Version: 2.0.2
4
4
  Summary: Python wrapper for GuardPoint 10 Access Control System
5
5
  Author: John Owen
6
6
  Maintainer-email: sales@sensoraccess.co.uk
7
+ License: Apache-2.0
7
8
  Requires-Python: >3.9.0
8
9
  Description-Content-Type: text/markdown
9
10
  License-File: LICENSE.txt
@@ -16,6 +17,7 @@ Requires-Dist: python-Levenshtein
16
17
  Dynamic: author
17
18
  Dynamic: description
18
19
  Dynamic: description-content-type
20
+ Dynamic: license
19
21
  Dynamic: license-file
20
22
  Dynamic: maintainer-email
21
23
  Dynamic: requires-dist
@@ -280,8 +280,17 @@ class CardholdersAPI:
280
280
  :raises ValueError: If neither `uid` nor `card_code` is provided.
281
281
  """
282
282
  if card_code:
283
+ cards = self.get_cards(cardCode=card_code)
284
+ if len(cards) > 0:
285
+ if cards[0].cardholderUID is not None:
286
+ return self._get_card_holder(cards[0].cardholderUID)
287
+ else:
288
+ return None
289
+ else:
290
+ return None
283
291
  # Part of the Cards_API
284
- return self.get_cardholder_by_card_code(card_code)
292
+ # (Broken API Call)
293
+ #return self.get_cardholder_by_card_code(card_code)
285
294
  else:
286
295
  return self._get_card_holder(uid)
287
296
 
@@ -336,10 +345,11 @@ class CardholdersAPI:
336
345
  "securityGroup," \
337
346
  "insideArea"
338
347
 
339
- if self.site_uid is not None:
340
- match_args = {'ownerSiteUID': self.site_uid}
341
- filter_str = _compose_filter(exact_match=match_args)
342
- url_query_params += ("&" + filter_str)
348
+ # Do not apply site filter, when looking for individuals
349
+ #if self.site_uid is not None:
350
+ # match_args = {'ownerSiteUID': self.site_uid}
351
+ # filter_str = _compose_filter(exact_match=match_args)
352
+ # url_query_params += ("&" + filter_str)
343
353
 
344
354
  code, json_body = self.gp_json_query("GET", url=(url + url_query_params))
345
355
 
@@ -1,7 +1,7 @@
1
1
  import validators
2
2
  from .guardpoint_utils import GuardPointResponse
3
3
  from .guardpoint_error import GuardPointError, GuardPointUnauthorized
4
- from .guardpoint_dataclasses import CardholderCustomizedField
4
+ from .guardpoint_dataclasses import CardholderCustomizedField, CustomizedField
5
5
 
6
6
 
7
7
  class CustomizedFieldsAPI:
@@ -14,6 +14,38 @@ class CustomizedFieldsAPI:
14
14
  Updates the custom fields for a specified cardholder.
15
15
  """
16
16
 
17
+ def get_custom_fields(self):
18
+ url = "/odata/API_CustomizedFields"
19
+ headers = {
20
+ 'Content-Type': 'application/json',
21
+ 'Accept': 'application/json'
22
+ }
23
+
24
+ code, json_body = self.gp_json_query("GET", headers=headers, url=url)
25
+
26
+ if code != 200:
27
+ error_msg = GuardPointResponse.extract_error_msg(json_body)
28
+
29
+ if code == 401:
30
+ raise GuardPointUnauthorized(f"Unauthorized - ({error_msg})")
31
+ elif code == 404: # Not Found
32
+ raise GuardPointError(f"CustomizedFields Not Found")
33
+ else:
34
+ raise GuardPointError(f"{error_msg}")
35
+
36
+ if not isinstance(json_body, dict):
37
+ raise GuardPointError("Badly formatted response.")
38
+ if 'value' not in json_body:
39
+ raise GuardPointError("Badly formatted response.")
40
+ if not isinstance(json_body['value'], list):
41
+ raise GuardPointError("Badly formatted response.")
42
+
43
+ customizedFields = []
44
+ for x in json_body['value']:
45
+ customizedFields.append(CustomizedField(x))
46
+ return customizedFields
47
+
48
+
17
49
  def update_custom_fields(self, cardholder_uid: str, customFields: CardholderCustomizedField):
18
50
  """
19
51
  Update custom fields for a specific cardholder.
@@ -36,7 +68,7 @@ class CustomizedFieldsAPI:
36
68
  if not validators.uuid(cardholder_uid):
37
69
  raise ValueError(f'Malformed Cardholder UID {cardholder_uid}')
38
70
 
39
- url = "/odata/API_CardholderCustomizedFields"
71
+ url = "/odata/API_CustomizedFields"
40
72
  url_query_params = f"({cardholder_uid})"
41
73
 
42
74
  headers = {
@@ -194,8 +194,16 @@ class CardholdersAPI:
194
194
  uid: str = None,
195
195
  card_code: str = None):
196
196
  if card_code:
197
+ cards = await self.get_cards(cardCode=card_code)
198
+ if len(cards) > 0:
199
+ if cards[0].cardholderUID is not None:
200
+ return await self._get_card_holder(cards[0].cardholderUID)
201
+ else:
202
+ return None
203
+ else:
204
+ return None
197
205
  # Part of the Cards_API
198
- return await self.get_cardholder_by_card_code(card_code)
206
+ # (Broken)return await self.get_cardholder_by_card_code(card_code)
199
207
  else:
200
208
  return await self._get_card_holder(uid)
201
209
 
@@ -237,10 +245,11 @@ class CardholdersAPI:
237
245
  "securityGroup," \
238
246
  "insideArea"
239
247
 
240
- if self.site_uid is not None:
241
- match_args = {'ownerSiteUID': self.site_uid}
242
- filter_str = _compose_filter(exact_match=match_args)
243
- url_query_params += ("&" + filter_str)
248
+ # Do not apply site filter, when looking for individuals
249
+ # if self.site_uid is not None:
250
+ # match_args = {'ownerSiteUID': self.site_uid}
251
+ # filter_str = _compose_filter(exact_match=match_args)
252
+ # url_query_params += ("&" + filter_str)
244
253
 
245
254
  code, json_body = await self.gp_json_query("GET", url=(url + url_query_params))
246
255
 
@@ -0,0 +1,67 @@
1
+ import validators
2
+ from ..guardpoint_utils import GuardPointResponse
3
+ from ..guardpoint_error import GuardPointError, GuardPointUnauthorized
4
+ from ..guardpoint_dataclasses import CardholderCustomizedField, CustomizedField
5
+
6
+
7
+ class CustomizedFieldsAPI:
8
+
9
+ async def get_custom_fields(self):
10
+ url = "/odata/API_CustomizedFields"
11
+ headers = {
12
+ 'Content-Type': 'application/json',
13
+ 'Accept': 'application/json'
14
+ }
15
+
16
+ code, json_body = await self.gp_json_query("GET", headers=headers, url=url)
17
+
18
+ if code != 200:
19
+ error_msg = GuardPointResponse.extract_error_msg(json_body)
20
+
21
+ if code == 401:
22
+ raise GuardPointUnauthorized(f"Unauthorized - ({error_msg})")
23
+ elif code == 404: # Not Found
24
+ raise GuardPointError(f"CustomizedFields Not Found")
25
+ else:
26
+ raise GuardPointError(f"{error_msg}")
27
+
28
+ if not isinstance(json_body, dict):
29
+ raise GuardPointError("Badly formatted response.")
30
+ if 'value' not in json_body:
31
+ raise GuardPointError("Badly formatted response.")
32
+ if not isinstance(json_body['value'], list):
33
+ raise GuardPointError("Badly formatted response.")
34
+
35
+ customizedFields = []
36
+ for x in json_body['value']:
37
+ customizedFields.append(CustomizedField(x))
38
+ return customizedFields
39
+
40
+ async def update_custom_fields(self, cardholder_uid: str, customFields: CardholderCustomizedField):
41
+ if not validators.uuid(cardholder_uid):
42
+ raise ValueError(f'Malformed Cardholder UID {cardholder_uid}')
43
+
44
+ url = "/odata/API_CardholderCustomizedFields"
45
+ url_query_params = f"({cardholder_uid})"
46
+
47
+ headers = {
48
+ 'Content-Type': 'application/json',
49
+ 'Accept': 'application/json',
50
+ # 'IgnoreNonEditable': ''
51
+ }
52
+
53
+ ch = customFields.dict(changed_only=True)
54
+
55
+ code, json_body = await self.gp_json_query("PATCH", headers=headers, url=(url + url_query_params), json_body=ch)
56
+
57
+ if code != 204: # HTTP NO_CONTENT
58
+ error_msg = GuardPointResponse.extract_error_msg(json_body)
59
+
60
+ if code == 401:
61
+ raise GuardPointUnauthorized(f"Unauthorized - ({error_msg})")
62
+ elif code == 404: # Not Found
63
+ raise GuardPointError(f"Cardholder Not Found")
64
+ else:
65
+ raise GuardPointError(f"{error_msg}")
66
+
67
+ return True
@@ -208,10 +208,15 @@ class GuardPointConnection:
208
208
  else:
209
209
  raw_body = json.dumps(json_body)
210
210
 
211
- headers = headers or {
212
- 'Content-Type': 'application/json',
213
- 'Accept': 'application/json'
214
- }
211
+ if len(raw_body) == 0:
212
+ headers = headers or {
213
+ 'Accept': 'application/json',
214
+ }
215
+ else:
216
+ headers = headers or {
217
+ 'Content-Type': 'application/json',
218
+ 'Accept': 'application/json'
219
+ }
215
220
 
216
221
  if auth_str:
217
222
  headers['Authorization'] = auth_str
@@ -62,6 +62,41 @@ class CardholderOrderBy(Enum):
62
62
  fromDateValid_DESC = 0,
63
63
  lastPassDate_DESC = 1
64
64
 
65
+ @dataclass
66
+ class CustomizedField:
67
+ customizedFieldType: str = ""
68
+ description: str = ""
69
+ cardholderCFName: str = ""
70
+ name: str = ""
71
+ uid: str = ""
72
+ booleanDefaultValue: any = None
73
+ dateTimeDefaultValue: any = None
74
+ fromValue: any = None
75
+ toValue: any = None
76
+ numberDefaultValue: any = None
77
+ minValue: any = None
78
+ maxValue: any = None
79
+ stringDefaultValue: str = ""
80
+ isMultiLine: any = None
81
+
82
+ def __init__(self, *args, **kwargs):
83
+ super().__init__()
84
+ cf_dict = sanitise_args(self, args, kwargs)
85
+
86
+ for property_name in cf_dict:
87
+ if isinstance(cf_dict[property_name], (str, type(None), bool, int, dict)):
88
+ setattr(self, property_name, cf_dict[property_name])
89
+
90
+ def dict(self):
91
+ cf_dict = {}
92
+ for k, v in asdict(self).items():
93
+ if isinstance(v, (list, dict, bool, int)):
94
+ cf_dict[k] = v
95
+ elif isinstance(v, type(None)):
96
+ cf_dict[k] = None
97
+ else:
98
+ cf_dict[k] = str(v)
99
+
65
100
  @dataclass
66
101
  class ManualEvent:
67
102
  uid: str = ""
@@ -1,9 +1,10 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyGuardPoint
3
- Version: 2.0.0
3
+ Version: 2.0.2
4
4
  Summary: Python wrapper for GuardPoint 10 Access Control System
5
5
  Author: John Owen
6
6
  Maintainer-email: sales@sensoraccess.co.uk
7
+ License: Apache-2.0
7
8
  Requires-Python: >3.9.0
8
9
  Description-Content-Type: text/markdown
9
10
  License-File: LICENSE.txt
@@ -16,6 +17,7 @@ Requires-Dist: python-Levenshtein
16
17
  Dynamic: author
17
18
  Dynamic: description
18
19
  Dynamic: description-content-type
20
+ Dynamic: license
19
21
  Dynamic: license-file
20
22
  Dynamic: maintainer-email
21
23
  Dynamic: requires-dist
@@ -5,7 +5,7 @@ long_description = open('README.rst').read()
5
5
  setup(name="pyGuardPoint",
6
6
  python_requires='>3.9.0',
7
7
  packages=find_packages(),
8
- version="2.0.0",
8
+ version="2.0.2",
9
9
  author="John Owen",
10
10
  description="Python wrapper for GuardPoint 10 Access Control System",
11
11
  long_description_content_type='text/markdown',
@@ -13,5 +13,6 @@ setup(name="pyGuardPoint",
13
13
  maintainer_email="sales@sensoraccess.co.uk",
14
14
  install_requires=['validators', 'fuzzywuzzy', 'cryptography', 'pysignalr>=1.3.0', 'websockets', 'python-Levenshtein'],
15
15
  #packages=['pyGuardPoint'],
16
+ license="Apache-2.0",
16
17
  license_files=('LICENSE.txt',),
17
18
  zip_safe=False)
@@ -1,36 +0,0 @@
1
- import validators
2
- from ..guardpoint_utils import GuardPointResponse
3
- from ..guardpoint_error import GuardPointError, GuardPointUnauthorized
4
- from ..guardpoint_dataclasses import CardholderCustomizedField
5
-
6
-
7
- class CustomizedFieldsAPI:
8
-
9
- async def update_custom_fields(self, cardholder_uid: str, customFields: CardholderCustomizedField):
10
- if not validators.uuid(cardholder_uid):
11
- raise ValueError(f'Malformed Cardholder UID {cardholder_uid}')
12
-
13
- url = "/odata/API_CardholderCustomizedFields"
14
- url_query_params = f"({cardholder_uid})"
15
-
16
- headers = {
17
- 'Content-Type': 'application/json',
18
- 'Accept': 'application/json',
19
- # 'IgnoreNonEditable': ''
20
- }
21
-
22
- ch = customFields.dict(changed_only=True)
23
-
24
- code, json_body = await self.gp_json_query("PATCH", headers=headers, url=(url + url_query_params), json_body=ch)
25
-
26
- if code != 204: # HTTP NO_CONTENT
27
- error_msg = GuardPointResponse.extract_error_msg(json_body)
28
-
29
- if code == 401:
30
- raise GuardPointUnauthorized(f"Unauthorized - ({error_msg})")
31
- elif code == 404: # Not Found
32
- raise GuardPointError(f"Cardholder Not Found")
33
- else:
34
- raise GuardPointError(f"{error_msg}")
35
-
36
- return True
File without changes
File without changes
File without changes