zscaler-sdk-python 0.9.3__tar.gz → 0.9.5__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 (99) hide show
  1. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/PKG-INFO +3 -3
  2. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/pyproject.toml +3 -3
  3. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/__init__.py +1 -1
  4. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zia/__init__.py +6 -3
  5. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zia/locations.py +20 -49
  6. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zia/traffic.py +1 -2
  7. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zpa/connectors.py +12 -3
  8. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zpa/microtenants.py +38 -7
  9. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zpa/service_edges.py +1 -1
  10. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/LICENSE.md +0 -0
  11. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/README.md +0 -0
  12. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/cache/__init__.py +0 -0
  13. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/cache/cache.py +0 -0
  14. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/cache/no_op_cache.py +0 -0
  15. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/cache/zscaler_cache.py +0 -0
  16. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/constants.py +0 -0
  17. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/errors/__init__.py +0 -0
  18. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/errors/error.py +0 -0
  19. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/errors/http_error.py +0 -0
  20. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/errors/zscaler_api_error.py +0 -0
  21. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/exceptions/__init__.py +0 -0
  22. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/exceptions/exceptions.py +0 -0
  23. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/logger.py +0 -0
  24. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/ratelimiter/__init__.py +0 -0
  25. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/ratelimiter/ratelimiter.py +0 -0
  26. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/user_agent.py +0 -0
  27. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/utils.py +0 -0
  28. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zcc/__init__.py +0 -0
  29. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zcc/client.py +0 -0
  30. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zcc/devices.py +0 -0
  31. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zcc/secrets.py +0 -0
  32. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zcon/__init__.py +0 -0
  33. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zcon/activation.py +0 -0
  34. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zcon/admin_and_role_management.py +0 -0
  35. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zcon/client.py +0 -0
  36. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zcon/ecgroups.py +0 -0
  37. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zcon/locations.py +0 -0
  38. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zcon/provisioning.py +0 -0
  39. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zdx/__init__.py +0 -0
  40. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zdx/admin.py +0 -0
  41. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zdx/alerts.py +0 -0
  42. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zdx/apps.py +0 -0
  43. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zdx/devices.py +0 -0
  44. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zdx/filters.py +0 -0
  45. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zdx/inventory.py +0 -0
  46. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zdx/troubleshooting.py +0 -0
  47. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zdx/users.py +0 -0
  48. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zdx/zdx_client.py +0 -0
  49. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zia/activate.py +0 -0
  50. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zia/admin_and_role_management.py +0 -0
  51. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zia/apptotal.py +0 -0
  52. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zia/audit_logs.py +0 -0
  53. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zia/authentication_settings.py +0 -0
  54. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zia/client.py +0 -0
  55. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zia/cloud_apps.py +0 -0
  56. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zia/cloudappcontrol.py +0 -0
  57. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zia/device_management.py +0 -0
  58. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zia/dlp.py +0 -0
  59. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zia/errors.py +0 -0
  60. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zia/firewall.py +0 -0
  61. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zia/forwarding_control.py +0 -0
  62. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zia/isolation_profile.py +0 -0
  63. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zia/labels.py +0 -0
  64. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zia/sandbox.py +0 -0
  65. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zia/security.py +0 -0
  66. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zia/ssl_inspection.py +0 -0
  67. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zia/url_categories.py +0 -0
  68. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zia/url_filtering.py +0 -0
  69. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zia/users.py +0 -0
  70. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zia/web_dlp.py +0 -0
  71. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zia/workload_groups.py +0 -0
  72. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zia/zpa_gateway.py +0 -0
  73. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zpa/README.md +0 -0
  74. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zpa/__init__.py +0 -0
  75. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zpa/app_segments.py +0 -0
  76. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zpa/app_segments_inspection.py +0 -0
  77. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zpa/app_segments_pra.py +0 -0
  78. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zpa/authdomains.py +0 -0
  79. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zpa/certificates.py +0 -0
  80. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zpa/client.py +0 -0
  81. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zpa/cloud_connector_groups.py +0 -0
  82. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zpa/emergency_access.py +0 -0
  83. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zpa/errors.py +0 -0
  84. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zpa/idp.py +0 -0
  85. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zpa/inspection.py +0 -0
  86. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zpa/isolation.py +0 -0
  87. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zpa/lss.py +0 -0
  88. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zpa/machine_groups.py +0 -0
  89. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zpa/policies.py +0 -0
  90. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zpa/posture_profiles.py +0 -0
  91. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zpa/privileged_remote_access.py +0 -0
  92. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zpa/provisioning.py +0 -0
  93. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zpa/saml_attributes.py +0 -0
  94. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zpa/scim_attributes.py +0 -0
  95. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zpa/scim_groups.py +0 -0
  96. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zpa/segment_groups.py +0 -0
  97. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zpa/server_groups.py +0 -0
  98. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zpa/servers.py +0 -0
  99. {zscaler_sdk_python-0.9.3 → zscaler_sdk_python-0.9.5}/zscaler/zpa/trusted_networks.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: zscaler-sdk-python
3
- Version: 0.9.3
3
+ Version: 0.9.5
4
4
  Summary: Official Python SDK for the Zscaler Products (Beta)
5
5
  Home-page: https://github.com/zscaler/zscaler-sdk-python
6
6
  License: MIT
@@ -32,7 +32,7 @@ Requires-Dist: flake8
32
32
  Requires-Dist: flatdict
33
33
  Requires-Dist: idna (>=3.10)
34
34
  Requires-Dist: okta (>=2.9.7)
35
- Requires-Dist: pycryptodomex
35
+ Requires-Dist: pycryptodomex (>=3.20.0)
36
36
  Requires-Dist: pydash (>=8.0.3) ; extra == "dev"
37
37
  Requires-Dist: python-box (>=7.2.0)
38
38
  Requires-Dist: python-dateutil
@@ -40,7 +40,7 @@ Requires-Dist: pytz (>=2024.2)
40
40
  Requires-Dist: pyyaml
41
41
  Requires-Dist: requests (>=2.32.3)
42
42
  Requires-Dist: responses (>=0.25.3)
43
- Requires-Dist: restfly
43
+ Requires-Dist: restfly (>=1.5.0)
44
44
  Requires-Dist: six
45
45
  Requires-Dist: xmltodict
46
46
  Requires-Dist: yarl
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "zscaler-sdk-python"
3
- version = "0.9.3"
3
+ version = "0.9.5"
4
4
  description = "Official Python SDK for the Zscaler Products (Beta)"
5
5
  authors = ["Zscaler, Inc. <devrel@zscaler.com>"]
6
6
  license = "MIT"
@@ -37,13 +37,13 @@ python-box = ">=7.2.0"
37
37
  python-dateutil = "*"
38
38
  requests = ">=2.32.3"
39
39
  responses = ">=0.25.3"
40
- restfly = "*"
40
+ restfly = ">=1.5.0"
41
41
  six = "*"
42
42
  flatdict = "*"
43
43
  pyyaml = "*"
44
44
  xmltodict = "*"
45
45
  yarl = "*"
46
- pycryptodomex = "*"
46
+ pycryptodomex = ">=3.20.0"
47
47
  aenum = "*"
48
48
  pydash = ">=8.0.3"
49
49
  flake8 = "*"
@@ -29,7 +29,7 @@ __license__ = "MIT"
29
29
  __contributors__ = [
30
30
  "William Guilherme",
31
31
  ]
32
- __version__ = "0.9.3"
32
+ __version__ = "0.9.5"
33
33
 
34
34
  from zscaler.zdx import ZDXClientHelper # noqa
35
35
  from zscaler.zia import ZIAClientHelper # noqa
@@ -382,13 +382,16 @@ class ZIAClientHelper(ZIAClient):
382
382
  formatted_resp = format_json_response(resp, box_attrs=dict())
383
383
  return formatted_resp
384
384
 
385
- def post(self, path, json=None, params=None, data=None, headers=None):
385
+ def post(self, path, json=None, params=None, data=None, headers=None, parse_json=True):
386
386
  should_wait, delay = self.rate_limiter.wait("POST")
387
387
  if should_wait:
388
388
  time.sleep(delay)
389
389
  resp = self.send("POST", path, json, params, data=data, headers=headers)
390
- formatted_resp = format_json_response(resp, box_attrs=dict())
391
- return formatted_resp
390
+ if parse_json:
391
+ formatted_resp = format_json_response(resp, box_attrs=dict())
392
+ return formatted_resp
393
+ else:
394
+ return resp
392
395
 
393
396
  def delete(self, path, json=None, params=None):
394
397
  should_wait, delay = self.rate_limiter.wait("DELETE")
@@ -43,8 +43,6 @@ class LocationsAPI:
43
43
  Specifies the page size. The default size is 100, but the maximum size is 1000.
44
44
  **search (str, optional):
45
45
  The search string used to partially match against a location's name and port attributes.
46
- **xff_enabled (bool, optional):
47
- Filter based on whether the Enforce XFF Forwarding setting is enabled or disabled for a location.
48
46
 
49
47
  Returns:
50
48
  :obj:`BoxList`: List of configured locations.
@@ -188,7 +186,8 @@ class LocationsAPI:
188
186
  description (str, optional):
189
187
  Additional notes or information regarding the location or sub-location. The description cannot
190
188
  exceed 1024 characters.
191
-
189
+ static_location_groups (list): IDs for static location groups.
190
+
192
191
  Returns:
193
192
  :obj:`Box`: The newly created location resource record
194
193
 
@@ -483,7 +482,7 @@ class LocationsAPI:
483
482
  raise Exception(f"API call failed with status {status_code}: {response.json()}")
484
483
  return response
485
484
 
486
- def list_location_groups(self) -> BoxList:
485
+ def list_location_groups(self, **kwargs) -> BoxList:
487
486
  """
488
487
  Return a list of location groups in ZIA.
489
488
 
@@ -491,7 +490,11 @@ class LocationsAPI:
491
490
  **kwargs: Optional keyword args.
492
491
 
493
492
  Keyword Args:
494
- groupType (str): The location group's type (i.e., Static or Dynamic).
493
+ name (str): The location group's name.
494
+ comments (str): Additional comments or information about the location group.
495
+ groupType (str): The location group's type (i.e., STATIC_GROUP or DYNAMIC_GROUP).
496
+ location_id (int): The unique identifier for a location within a location group.
497
+ last_mod_user (str): The admin who modified the location group last.
495
498
 
496
499
  Returns:
497
500
  :obj:`BoxList`: A list of location group resource records.
@@ -500,7 +503,14 @@ class LocationsAPI:
500
503
  Get a list of all configured location groups:
501
504
  >>> location = zia.locations.list_location_groups()
502
505
  """
503
- return self.rest.get("locations/groups")
506
+ return BoxList(
507
+ Iterator(
508
+ self.rest,
509
+ f"locations/groups",
510
+ max_pages=1,
511
+ **kwargs,
512
+ )
513
+ )
504
514
 
505
515
  def get_location_group_by_id(self, group_id: int) -> Box:
506
516
  """
@@ -518,25 +528,6 @@ class LocationsAPI:
518
528
  """
519
529
  return self.rest.get(f"locations/groups/{group_id}")
520
530
 
521
- def get_location_group_by_name(self, group_name: str, page: int = 1, page_size: int = 100) -> Box:
522
- """
523
- Return a specific location group by its name in ZIA.
524
-
525
- Args:
526
- group_name (str): The name of the location group.
527
- page (int, optional): Page number to retrieve. Defaults to 1.
528
- page_size (int, optional): Number of records per page. Defaults to 100.
529
-
530
- Returns:
531
- :obj:`Box`: A location group resource record.
532
-
533
- Examples:
534
- Get a specific location group by its name:
535
- >>> location = zia.locations.get_location_group_by_name("Unassigned Locations")
536
- """
537
- params = {"page": page, "pageSize": page_size, "search": group_name}
538
- return self.rest.get("locations/groups", params=params)
539
-
540
531
  def list_location_groups_lite(self, page: int = 1, page_size: int = 100) -> BoxList:
541
532
  """
542
533
  Returns a list of location groups (lite version) by their ID where only name and ID is returned in ZIA.
@@ -545,7 +536,7 @@ class LocationsAPI:
545
536
  **kwargs: Optional keyword args.
546
537
 
547
538
  Keyword Args:
548
- groupType (str): The location group's type (i.e., Static or Dynamic).
539
+ groupType (str): The location group's type (i.e., STATIC_GROUP or DYNAMIC_GROUP).
549
540
 
550
541
  Returns:
551
542
  :obj:`BoxList`: A list of location group resource records.
@@ -573,25 +564,6 @@ class LocationsAPI:
573
564
  """
574
565
  return self.rest.get(f"locations/groups/lite/{group_id}")
575
566
 
576
- def get_location_group_lite_by_name(self, group_name: str, page: int = 1, page_size: int = 100) -> BoxList:
577
- """
578
- Return specific location groups (lite version) by their name where only name and ID is returned in ZIA.
579
-
580
- Args:
581
- group_name (str): The name of the location group.
582
- page (int, optional): Page number to retrieve. Defaults to 1.
583
- page_size (int, optional): Number of records per page. Defaults to 100.
584
-
585
- Returns:
586
- :obj:`BoxList`: A list of location group resource records with only ID and name.
587
-
588
- Examples:
589
- Get specific location groups (lite version) by name:
590
- >>> locations = zia.locations.get_location_group_lite_by_name("Unassigned Locations")
591
- """
592
- params = {"page": page, "pageSize": page_size, "search": group_name}
593
- return self.rest.get("locations/groups/lite", params=params)
594
-
595
567
  def list_location_groups_count(self, **kwargs) -> BoxList:
596
568
  """
597
569
  Returns a list of location groups for your organization.
@@ -600,7 +572,7 @@ class LocationsAPI:
600
572
  **kwargs: Optional keyword args.
601
573
 
602
574
  Keyword Args:
603
- group_type (str): The location group's type (i.e., Static or Dynamic).
575
+ group_type (str): The location group's type (i.e., STATIC_GROUP or DYNAMIC_GROUP).
604
576
  last_mod_user (str): The admin who modified the location group last.
605
577
  version (int): The version parameter is for Zscaler internal use only. Used by the service for backup operations.
606
578
  name (str): The location group's name.
@@ -612,7 +584,7 @@ class LocationsAPI:
612
584
 
613
585
  Examples:
614
586
  Gets the list of location groups for your organization:
615
- >>> location = zia.locations.list_location_groups_count(group_type='Static', name='Corporate')
587
+ >>> location = zia.locations.list_location_groups_count(group_type='STATIC_GROUP', name='Corporate')
616
588
  """
617
589
  params = {}
618
590
  optional_params = ["group_type", "last_mod_user", "version", "name", "comments", "location_id"]
@@ -693,5 +665,4 @@ class LocationsAPI:
693
665
 
694
666
  """
695
667
  return BoxList(Iterator(self.rest, "region/search", **kwargs))
696
- # data, _ = self.rest.get_paginated_data(path="region/search", params=kwargs)
697
- # return BoxList([Box(city) for city in data])
668
+
@@ -523,13 +523,12 @@ class TrafficForwardingAPI:
523
523
  payload = {
524
524
  "ipAddress": ip_address,
525
525
  }
526
- response = self.rest.post("staticIP/validate", json=payload)
526
+ response = self.rest.post("staticIP/validate", json=payload, parse_json=False)
527
527
 
528
528
  # Check if the status code is 200 and the response body text is "SUCCESS"
529
529
  if response.status_code == 200 and response.text.strip().upper() == "SUCCESS":
530
530
  return True
531
531
  else:
532
- # Optionally, you could log response.text or response.status_code here for debugging
533
532
  return False
534
533
 
535
534
  def update_static_ip(self, static_ip_id: str, **kwargs) -> Box:
@@ -159,7 +159,7 @@ class AppConnectorControllerAPI:
159
159
  params["microtenantId"] = kwargs.pop("microtenant_id")
160
160
  return self.rest.delete(f"connector/{connector_id}", params=params).status_code
161
161
 
162
- def bulk_delete_connectors(self, connector_ids: list, **kwargs) -> int:
162
+ def bulk_delete_connectors(self, connector_ids: list, **kwargs) -> Box:
163
163
  """
164
164
  Deletes all specified App Connectors from ZPA.
165
165
 
@@ -177,7 +177,16 @@ class AppConnectorControllerAPI:
177
177
  params = {}
178
178
  if "microtenant_id" in kwargs:
179
179
  params["microtenantId"] = kwargs.pop("microtenant_id")
180
- return self.rest.post("connector/bulkDelete", json=payload)
180
+
181
+ response = self.rest.post("connector/bulkDelete", json=payload, params=params)
182
+
183
+ if isinstance(response, Response):
184
+ # Check for HTTP status and handle errors
185
+ if response.status_code != 200:
186
+ raise Exception(f"API call failed with status {response.status_code}: {response.json()}")
187
+
188
+ # If successful, return the response
189
+ return response
181
190
 
182
191
  def list_connector_groups(self, **kwargs) -> BoxList:
183
192
  """
@@ -590,4 +599,4 @@ class AppConnectorControllerAPI:
590
599
 
591
600
  """
592
601
  list, _ = self.rest.get_paginated_data(path="/visible/versionProfiles", **kwargs, api_version="v1")
593
- return list
602
+ return list
@@ -60,10 +60,14 @@ class MicrotenantsAPI:
60
60
 
61
61
  """
62
62
  response = self.rest.get("/microtenants/%s" % (microtenant_id))
63
+
64
+ # If the response is not a Box (indicating an error), return None or handle the error
63
65
  if isinstance(response, Response):
64
66
  status_code = response.status_code
65
67
  if status_code != 200:
66
- return None
68
+ raise Exception(f"Failed to retrieve microtenant: {status_code} - {response.text}")
69
+
70
+ # Otherwise, return the formatted Box object
67
71
  return response
68
72
 
69
73
  def get_microtenant_summary(self) -> Box:
@@ -189,17 +193,44 @@ class MicrotenantsAPI:
189
193
  ... )
190
194
 
191
195
  """
192
- # Set payload to value of existing record
193
- payload = {snake_to_camel(k): v for k, v in self.get_microtenant(microtenant_id).items()}
194
-
195
- # Add optional parameters to payload
196
+ # Retrieve existing microtenant data
197
+ existing_microtenant_response = self.get_microtenant(microtenant_id)
198
+
199
+ # Handle Response object (in case of error)
200
+ if isinstance(existing_microtenant_response, Response):
201
+ if existing_microtenant_response.status_code != 200:
202
+ raise Exception(f"Failed to retrieve microtenant: {existing_microtenant_response.status_code}")
203
+ # If there's content, parse the response as JSON
204
+ if existing_microtenant_response.text.strip():
205
+ existing_microtenant = existing_microtenant_response.json()
206
+ else:
207
+ existing_microtenant = {} # Treat as empty, no error
208
+ else:
209
+ existing_microtenant = existing_microtenant_response
210
+
211
+ # Prepare the payload
212
+ payload = {snake_to_camel(k): v for k, v in existing_microtenant.items()}
213
+
214
+ # Add optional parameters from kwargs
196
215
  for key, value in kwargs.items():
197
216
  payload[snake_to_camel(key)] = value
198
217
 
199
- resp = self.rest.put(f"microtenants/{microtenant_id}", json=payload).status_code
200
- if not isinstance(resp, Response):
218
+ # Send the PUT request to update the microtenant
219
+ resp = self.rest.put(f"microtenants/{microtenant_id}", json=payload)
220
+
221
+ # Handle 204 No Content as success
222
+ if resp.status_code == 204:
223
+ print(f"Update successful for microtenant {microtenant_id} (204 No Content).")
224
+ return self.get_microtenant(microtenant_id)
225
+
226
+ # Handle 200 OK as success
227
+ if resp.status_code == 200:
228
+ print(f"Update successful for microtenant {microtenant_id} (200 OK).")
201
229
  return self.get_microtenant(microtenant_id)
202
230
 
231
+ # Raise exception for any other status code
232
+ raise Exception(f"Failed to update microtenant: {resp.status_code}, {resp.text}")
233
+
203
234
  def delete_microtenant(self, microtenant_id: str) -> int:
204
235
  """
205
236
  Delete the specified microtenant.
@@ -155,7 +155,7 @@ class ServiceEdgesAPI:
155
155
  params["microtenantId"] = kwargs.pop("microtenant_id")
156
156
  return self.rest.delete(f"serviceEdge/{service_edge_id}", params=params).status_code
157
157
 
158
- def bulk_delete_service_edges(self, service_edge_ids: list, **kwargs) -> int:
158
+ def bulk_delete_service_edges(self, service_edge_ids: list, **kwargs) -> Box:
159
159
  """
160
160
  Bulk deletes the specified Service Edges from ZPA.
161
161