Skip to content

Commit 96f1a52

Browse files
committed
introduce descopeResponse to sdk
1 parent 65229e0 commit 96f1a52

File tree

11 files changed

+174
-874
lines changed

11 files changed

+174
-874
lines changed

descope/http_client.py

Lines changed: 104 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,102 @@ def sdk_version():
4343
}
4444

4545

46+
class DescopeResponse:
47+
def __init__(self, response):
48+
self.raw = response
49+
self._json_data = None
50+
51+
def json(self):
52+
if self._json_data is None:
53+
self._json_data = self.raw.json()
54+
return self._json_data
55+
56+
# Make it dict-compatible for backward compatibility
57+
def __getitem__(self, key):
58+
return self.json()[key]
59+
60+
def __contains__(self, key):
61+
return key in self.json()
62+
63+
def keys(self):
64+
return self.json().keys()
65+
66+
def values(self):
67+
return self.json().values()
68+
69+
def items(self):
70+
return self.json().items()
71+
72+
def get(self, key, default=None):
73+
return self.json().get(key, default)
74+
75+
# Make it print like a dict for backward compatibility
76+
def __str__(self):
77+
return str(self.json())
78+
79+
def __repr__(self):
80+
return repr(self.json())
81+
82+
# Make it behave like a dict in boolean context
83+
def __bool__(self):
84+
return bool(self.json())
85+
86+
def __len__(self):
87+
return len(self.json())
88+
89+
# Equality comparison - compare the underlying JSON data
90+
def __eq__(self, other):
91+
if isinstance(other, DescopeResponse):
92+
return self.json() == other.json()
93+
# Allow comparison with dict/list directly
94+
return self.json() == other
95+
96+
def __ne__(self, other):
97+
return not self.__eq__(other)
98+
99+
# Iteration support for list responses
100+
def __iter__(self):
101+
return iter(self.json())
102+
103+
# Hashing support (for use in sets/dicts)
104+
def __hash__(self):
105+
json_data = self.json()
106+
if isinstance(json_data, dict):
107+
return hash(tuple(sorted(json_data.items())))
108+
elif isinstance(json_data, list):
109+
return hash(tuple(json_data))
110+
return hash(json_data)
111+
112+
# Delegate properties
113+
@property
114+
def headers(self):
115+
return self.raw.headers
116+
117+
@property
118+
def status_code(self):
119+
return self.raw.status_code
120+
121+
@property
122+
def cookies(self):
123+
return self.raw.cookies
124+
125+
@property
126+
def text(self):
127+
return self.raw.text
128+
129+
@property
130+
def content(self):
131+
return self.raw.content
132+
133+
@property
134+
def url(self):
135+
return self.raw.url
136+
137+
@property
138+
def ok(self):
139+
return self.raw.ok
140+
141+
46142
class HTTPClient:
47143
def __init__(
48144
self,
@@ -80,7 +176,7 @@ def get(
80176
params=None,
81177
allow_redirects: Optional[bool] = True,
82178
pswd: Optional[str] = None,
83-
) -> requests.Response:
179+
) -> DescopeResponse:
84180
response = requests.get(
85181
f"{self.base_url}{uri}",
86182
headers=self._get_default_headers(pswd),
@@ -90,7 +186,7 @@ def get(
90186
timeout=self.timeout_seconds,
91187
)
92188
self._raise_from_response(response)
93-
return response
189+
return DescopeResponse(response)
94190

95191
def post(
96192
self,
@@ -100,7 +196,7 @@ def post(
100196
params=None,
101197
pswd: Optional[str] = None,
102198
base_url: Optional[str] = None,
103-
) -> requests.Response:
199+
) -> DescopeResponse:
104200
response = requests.post(
105201
f"{base_url or self.base_url}{uri}",
106202
headers=self._get_default_headers(pswd),
@@ -111,7 +207,7 @@ def post(
111207
timeout=self.timeout_seconds,
112208
)
113209
self._raise_from_response(response)
114-
return response
210+
return DescopeResponse(response)
115211

116212
def patch(
117213
self,
@@ -120,7 +216,7 @@ def patch(
120216
body: Optional[Union[dict, list[dict], list[str]]],
121217
params=None,
122218
pswd: Optional[str] = None,
123-
) -> requests.Response:
219+
) -> DescopeResponse:
124220
response = requests.patch(
125221
f"{self.base_url}{uri}",
126222
headers=self._get_default_headers(pswd),
@@ -131,15 +227,15 @@ def patch(
131227
timeout=self.timeout_seconds,
132228
)
133229
self._raise_from_response(response)
134-
return response
230+
return DescopeResponse(response)
135231

136232
def delete(
137233
self,
138234
uri: str,
139235
*,
140236
params=None,
141237
pswd: Optional[str] = None,
142-
) -> requests.Response:
238+
) -> DescopeResponse:
143239
response = requests.delete(
144240
f"{self.base_url}{uri}",
145241
params=params,
@@ -149,7 +245,7 @@ def delete(
149245
timeout=self.timeout_seconds,
150246
)
151247
self._raise_from_response(response)
152-
return response
248+
return DescopeResponse(response)
153249

154250
def get_default_headers(self, pswd: Optional[str] = None) -> dict:
155251
return self._get_default_headers(pswd)

descope/management/access_key.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ def create(
6464
permitted_ips,
6565
),
6666
)
67-
return response.json()
67+
return response
6868

6969
def load(
7070
self,
@@ -88,7 +88,7 @@ def load(
8888
uri=MgmtV1.access_key_load_path,
8989
params={"id": id},
9090
)
91-
return response.json()
91+
return response
9292

9393
def search_all_access_keys(
9494
self,
@@ -114,7 +114,7 @@ def search_all_access_keys(
114114
MgmtV1.access_keys_search_path,
115115
body={"tenantIds": tenant_ids},
116116
)
117-
return response.json()
117+
return response
118118

119119
def update(
120120
self,

descope/management/authz.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ def load_schema(self) -> dict:
6868
response = self._http.post(
6969
MgmtV1.authz_schema_load,
7070
)
71-
return response.json()["schema"]
71+
return response["schema"]
7272

7373
def save_namespace(
7474
self, namespace: dict, old_name: str = "", schema_name: str = ""
@@ -265,7 +265,7 @@ def has_relations(
265265
MgmtV1.authz_re_has_relations,
266266
body={"relationQueries": relation_queries},
267267
)
268-
return response.json()["relationQueries"]
268+
return response["relationQueries"]
269269

270270
def who_can_access(
271271
self, resource: str, relation_definition: str, namespace: str
@@ -289,7 +289,7 @@ def who_can_access(
289289
"namespace": namespace,
290290
},
291291
)
292-
return response.json()["targets"]
292+
return response["targets"]
293293

294294
def resource_relations(self, resource: str) -> List[dict]:
295295
"""
@@ -306,7 +306,7 @@ def resource_relations(self, resource: str) -> List[dict]:
306306
MgmtV1.authz_re_resource,
307307
body={"resource": resource},
308308
)
309-
return response.json()["relations"]
309+
return response["relations"]
310310

311311
def targets_relations(self, targets: List[str]) -> List[dict]:
312312
"""
@@ -323,7 +323,7 @@ def targets_relations(self, targets: List[str]) -> List[dict]:
323323
MgmtV1.authz_re_targets,
324324
body={"targets": targets},
325325
)
326-
return response.json()["relations"]
326+
return response["relations"]
327327

328328
def what_can_target_access(self, target: str) -> List[dict]:
329329
"""
@@ -340,7 +340,7 @@ def what_can_target_access(self, target: str) -> List[dict]:
340340
MgmtV1.authz_re_target_all,
341341
body={"target": target},
342342
)
343-
return response.json()["relations"]
343+
return response["relations"]
344344

345345
def what_can_target_access_with_relation(
346346
self, target: str, relation_definition: str, namespace: str
@@ -365,7 +365,7 @@ def what_can_target_access_with_relation(
365365
"namespace": namespace,
366366
},
367367
)
368-
return response.json()["relations"]
368+
return response["relations"]
369369

370370
def get_modified(self, since: Optional[datetime] = None) -> dict:
371371
"""
@@ -388,4 +388,4 @@ def get_modified(self, since: Optional[datetime] = None) -> dict:
388388
)
389389
},
390390
)
391-
return response.json()["relations"]
391+
return response["relations"]

descope/management/fga.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ def check(
133133
return list(
134134
map(
135135
lambda tuple: {"relation": tuple["tuple"], "allowed": tuple["allowed"]},
136-
response.json()["tuples"],
136+
response["tuples"],
137137
)
138138
)
139139

@@ -149,7 +149,7 @@ def load_resources_details(self, resource_identifiers: List[dict]) -> List[dict]
149149
MgmtV1.fga_resources_load,
150150
body={"resourceIdentifiers": resource_identifiers},
151151
)
152-
return response.json().get("resourcesDetails", [])
152+
return response.get("resourcesDetails", [])
153153

154154
def save_resources_details(self, resources_details: List[dict]) -> None:
155155
"""

descope/management/group.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ def load_all_groups(
4141
"tenantId": tenant_id,
4242
},
4343
)
44-
return response.json()
44+
return response
4545

4646
def load_all_groups_for_members(
4747
self,
@@ -88,7 +88,7 @@ def load_all_groups_for_members(
8888
"userIds": user_ids,
8989
},
9090
)
91-
return response.json()
91+
return response
9292

9393
def load_all_group_members(
9494
self,
@@ -129,4 +129,4 @@ def load_all_group_members(
129129
"groupId": group_id,
130130
},
131131
)
132-
return response.json()
132+
return response

descope/management/project.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,7 @@ def list_projects(
6363
MgmtV1.project_list_projects,
6464
body={},
6565
)
66-
resp = response.json()
67-
66+
resp = response
6867
projects = resp["projects"]
6968
# Apply the function to the projects list
7069
formatted_projects = self.remove_tag_field(projects)
@@ -103,7 +102,7 @@ def clone(
103102
"tags": tags,
104103
},
105104
)
106-
return response.json()
105+
return response
107106

108107
def export_project(
109108
self,
@@ -125,7 +124,7 @@ def export_project(
125124
MgmtV1.project_export,
126125
body={},
127126
)
128-
return response.json()["files"]
127+
return response["files"]
129128

130129
def import_project(
131130
self,

descope/management/role.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ def load_all(
114114
response = self._http.get(
115115
MgmtV1.role_load_all_path,
116116
)
117-
return response.json()
117+
return response
118118

119119
def search(
120120
self,
@@ -157,4 +157,4 @@ def search(
157157
MgmtV1.role_search_path,
158158
body=body,
159159
)
160-
return response.json()
160+
return response

descope/management/sso_application.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ def create_oidc_application(
5656
force_authentication,
5757
),
5858
)
59-
return response.json()
59+
return response
6060

6161
def create_saml_application(
6262
self,
@@ -153,7 +153,7 @@ def create_saml_application(
153153
logout_redirect_url,
154154
),
155155
)
156-
return response.json()
156+
return response
157157

158158
def update_oidc_application(
159159
self,
@@ -324,7 +324,7 @@ def load(
324324
AuthException: raised if load operation fails
325325
"""
326326
response = self._http.get(MgmtV1.sso_application_load_path, params={"id": id})
327-
return response.json()
327+
return response
328328

329329
def load_all(
330330
self,
@@ -346,7 +346,7 @@ def load_all(
346346
AuthException: raised if load operation fails
347347
"""
348348
response = self._http.get(MgmtV1.sso_application_load_all_path)
349-
return response.json()
349+
return response
350350

351351
@staticmethod
352352
def _compose_create_update_oidc_body(

0 commit comments

Comments
 (0)