Skip to content

Commit 4bb4b47

Browse files
committed
pangea-sdk: add expires_at to AuthZ tuples
1 parent d8f9f2b commit 4bb4b47

File tree

4 files changed

+113
-58
lines changed

4 files changed

+113
-58
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## Unreleased
99

10+
### Added
11+
12+
- AuthZ: `expires_at` to tuples.
13+
1014
## 6.0.0 - 2025-04-21
1115

1216
### Added

packages/pangea-sdk/pangea/asyncio/services/authz.py

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
from __future__ import annotations
55

6-
from typing import Any, Dict, List, Optional
6+
from typing import Any
77

88
from pangea.asyncio.services.base import ServiceBaseAsync
99
from pangea.config import PangeaConfig
@@ -73,14 +73,14 @@ def __init__(
7373

7474
super().__init__(token, config, logger_name, config_id=config_id)
7575

76-
async def tuple_create(self, tuples: List[Tuple]) -> PangeaResponse[TupleCreateResult]:
76+
async def tuple_create(self, tuples: list[Tuple]) -> PangeaResponse[TupleCreateResult]:
7777
"""Create tuples.
7878
7979
Create tuples in the AuthZ Service. The request will fail if there is no schema
8080
or the tuples do not validate against the schema.
8181
8282
Args:
83-
tuples (List[Tuple]): List of tuples to be created.
83+
tuples: Tuples to be created.
8484
8585
Raises:
8686
PangeaAPIException: If an API Error happens.
@@ -110,10 +110,10 @@ async def tuple_create(self, tuples: List[Tuple]) -> PangeaResponse[TupleCreateR
110110
async def tuple_list(
111111
self,
112112
filter: TupleListFilter,
113-
size: Optional[int] = None,
114-
last: Optional[str] = None,
115-
order: Optional[ItemOrder] = None,
116-
order_by: Optional[TupleOrderBy] = None,
113+
size: int | None = None,
114+
last: str | None = None,
115+
order: ItemOrder | None = None,
116+
order_by: TupleOrderBy | None = None,
117117
) -> PangeaResponse[TupleListResult]:
118118
"""List tuples.
119119
@@ -122,11 +122,11 @@ async def tuple_list(
122122
is empty it will return all the tuples.
123123
124124
Args:
125-
filter (TupleListFilter): The filter for listing tuples.
126-
size (Optional[int]): The size of the result set. Default is None.
127-
last (Optional[str]): The last token from a previous response. Default is None.
128-
order (Optional[ItemOrder]): Order results asc(ending) or desc(ending).
129-
order_by (Optional[TupleOrderBy]): Which field to order results by.
125+
filter: The filter for listing tuples.
126+
size: The size of the result set. Default is None.
127+
last: The last token from a previous response. Default is None.
128+
order: Order results asc(ending) or desc(ending).
129+
order_by: Which field to order results by.
130130
131131
Raises:
132132
PangeaAPIException: If an API Error happens.
@@ -144,13 +144,13 @@ async def tuple_list(
144144
)
145145
return await self.request.post("v1/tuple/list", TupleListResult, data=input_data.model_dump(exclude_none=True))
146146

147-
async def tuple_delete(self, tuples: List[Tuple]) -> PangeaResponse[TupleDeleteResult]:
147+
async def tuple_delete(self, tuples: list[Tuple]) -> PangeaResponse[TupleDeleteResult]:
148148
"""Delete tuples.
149149
150150
Delete tuples in the AuthZ Service.
151151
152152
Args:
153-
tuples (List[Tuple]): List of tuples to be deleted.
153+
tuples: Tuples to be deleted.
154154
155155
Raises:
156156
PangeaAPIException: If an API Error happens.
@@ -182,8 +182,8 @@ async def check(
182182
resource: Resource,
183183
action: str,
184184
subject: Subject,
185-
debug: Optional[bool] = None,
186-
attributes: Optional[Dict[str, Any]] = None,
185+
debug: bool | None = None,
186+
attributes: dict[str, Any] | None = None,
187187
) -> PangeaResponse[CheckResult]:
188188
"""Perform a check request.
189189
@@ -192,9 +192,9 @@ async def check(
192192
Args:
193193
resource (Resource): The resource to check.
194194
action (str): The action to check.
195-
subject (Subject): The subject to check.
196-
debug (Optional[bool]): Setting this value to True will provide a detailed analysis of the check.
197-
attributes (Optional[Dict[str, Any]]): Additional attributes for the check.
195+
subject: The subject to check.
196+
debug: Setting this value to True will provide a detailed analysis of the check.
197+
attributes: Additional attributes for the check.
198198
199199
Raises:
200200
PangeaAPIException: If an API Error happens.
@@ -217,18 +217,18 @@ async def check(
217217
return await self.request.post("v1/check", CheckResult, data=input_data.model_dump(exclude_none=True))
218218

219219
async def list_resources(
220-
self, type: str, action: str, subject: Subject, attributes: Optional[Dict[str, Any]] = None
220+
self, type: str, action: str, subject: Subject, attributes: dict[str, Any] | None = None
221221
) -> PangeaResponse[ListResourcesResult]:
222222
"""List resources.
223223
224224
Given a type, action, and subject, list all the resources in the
225225
type that the subject has access to the action with.
226226
227227
Args:
228-
type (str): The type to filter resources.
229-
action (str): The action to filter resources.
230-
subject (Subject): The subject to filter resources.
231-
attributes (Optional[Dict[str, Any]]): A JSON object of attribute data.
228+
type: The type to filter resources.
229+
action: The action to filter resources.
230+
subject: The subject to filter resources.
231+
attributes: A JSON object of attribute data.
232232
233233
Raises:
234234
PangeaAPIException: If an API Error happens.
@@ -252,17 +252,17 @@ async def list_resources(
252252
)
253253

254254
async def list_subjects(
255-
self, resource: Resource, action: str, attributes: Optional[Dict[str, Any]] = None
255+
self, resource: Resource, action: str, attributes: dict[str, Any] | None = None
256256
) -> PangeaResponse[ListSubjectsResult]:
257257
"""List subjects.
258258
259259
Given a resource and an action, return the list of subjects who have
260260
access to the action for the given resource.
261261
262262
Args:
263-
resource (Resource): The resource to filter subjects.
264-
action (str): The action to filter subjects.
265-
attributes (Optional[Dict[str, Any]]): A JSON object of attribute data.
263+
resource: The resource to filter subjects.
264+
action: The action to filter subjects.
265+
attributes: A JSON object of attribute data.
266266
267267
Raises:
268268
PangeaAPIException: If an API Error happens.

packages/pangea-sdk/pangea/services/authz.py

Lines changed: 65 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ class Tuple(PangeaResponseResult):
5151
resource: Resource
5252
relation: str
5353
subject: Subject
54+
expires_at: Optional[str] = None
55+
"""A time in ISO-8601 format"""
5456

5557

5658
class TupleCreateRequest(APIRequestModel):
@@ -63,23 +65,51 @@ class TupleCreateResult(PangeaResponseResult):
6365

6466
class TupleListFilter(APIRequestModel):
6567
resource_type: Optional[str] = None
68+
"""Only records where resource type equals this value."""
6669
resource_type__contains: Optional[List[str]] = None
70+
"""Only records where resource type includes each substring."""
6771
resource_type__in: Optional[List[str]] = None
72+
"""Only records where resource type equals one of the provided substrings."""
6873
resource_id: Optional[str] = None
74+
"""Only records where resource id equals this value."""
6975
resource_id__contains: Optional[List[str]] = None
76+
"""Only records where resource id includes each substring."""
7077
resource_id__in: Optional[List[str]] = None
78+
"""Only records where resource id equals one of the provided substrings."""
7179
relation: Optional[str] = None
80+
"""Only records where relation equals this value."""
7281
relation__contains: Optional[List[str]] = None
82+
"""Only records where relation includes each substring."""
7383
relation__in: Optional[List[str]] = None
84+
"""Only records where relation equals one of the provided substrings."""
7485
subject_type: Optional[str] = None
86+
"""Only records where subject type equals this value."""
7587
subject_type__contains: Optional[List[str]] = None
88+
"""Only records where subject type includes each substring."""
7689
subject_type__in: Optional[List[str]] = None
90+
"""Only records where subject type equals one of the provided substrings."""
7791
subject_id: Optional[str] = None
92+
"""Only records where subject id equals this value."""
7893
subject_id__contains: Optional[List[str]] = None
94+
"""Only records where subject id includes each substring."""
7995
subject_id__in: Optional[List[str]] = None
96+
"""Only records where subject id equals one of the provided substrings."""
8097
subject_action: Optional[str] = None
98+
"""Only records where subject action equals this value."""
8199
subject_action__contains: Optional[List[str]] = None
100+
"""Only records where subject action includes each substring."""
82101
subject_action__in: Optional[List[str]] = None
102+
"""Only records where subject action equals one of the provided substrings."""
103+
expires_at: Optional[str] = None
104+
"""Only records where expires_at equals this value."""
105+
expires_at__gt: Optional[str] = None
106+
"""Only records where expires_at is greater than this value."""
107+
expires_at__gte: Optional[str] = None
108+
"""Only records where expires_at is greater than or equal to this value."""
109+
expires_at__lt: Optional[str] = None
110+
"""Only records where expires_at is less than this value."""
111+
expires_at__lte: Optional[str] = None
112+
"""Only records where expires_at is less than or equal to this value."""
83113

84114

85115
class TupleListRequest(APIRequestModel):
@@ -109,7 +139,9 @@ class CheckRequest(APIRequestModel):
109139
action: str
110140
subject: Subject
111141
debug: Optional[bool] = None
142+
"""In the event of an allowed check, return a path that granted access."""
112143
attributes: Optional[Dict[str, Any]] = None
144+
"""A JSON object of attribute data."""
113145

114146

115147
class DebugPath(APIResponseModel):
@@ -145,6 +177,8 @@ class ListSubjectsRequest(APIRequestModel):
145177
resource: Resource
146178
action: str
147179
attributes: Optional[Dict[str, Any]] = None
180+
debug: Optional[bool] = None
181+
"""Return a path for each found subject"""
148182

149183

150184
class ListSubjectsResult(PangeaResponseResult):
@@ -194,14 +228,14 @@ def __init__(
194228

195229
super().__init__(token, config, logger_name, config_id=config_id)
196230

197-
def tuple_create(self, tuples: List[Tuple]) -> PangeaResponse[TupleCreateResult]:
231+
def tuple_create(self, tuples: list[Tuple]) -> PangeaResponse[TupleCreateResult]:
198232
"""Create tuples.
199233
200234
Create tuples in the AuthZ Service. The request will fail if there is no schema
201235
or the tuples do not validate against the schema.
202236
203237
Args:
204-
tuples (List[Tuple]): List of tuples to be created.
238+
tuples: Tuples to be created.
205239
206240
Raises:
207241
PangeaAPIException: If an API Error happens.
@@ -229,10 +263,10 @@ def tuple_create(self, tuples: List[Tuple]) -> PangeaResponse[TupleCreateResult]
229263
def tuple_list(
230264
self,
231265
filter: TupleListFilter,
232-
size: Optional[int] = None,
233-
last: Optional[str] = None,
234-
order: Optional[ItemOrder] = None,
235-
order_by: Optional[TupleOrderBy] = None,
266+
size: int | None = None,
267+
last: str | None = None,
268+
order: ItemOrder | None = None,
269+
order_by: TupleOrderBy | None = None,
236270
) -> PangeaResponse[TupleListResult]:
237271
"""List tuples.
238272
@@ -241,11 +275,11 @@ def tuple_list(
241275
is empty it will return all the tuples.
242276
243277
Args:
244-
filter (TupleListFilter): The filter for listing tuples.
245-
size (Optional[int]): The size of the result set. Default is None.
246-
last (Optional[str]): The last token from a previous response. Default is None.
247-
order (Optional[ItemOrder]): Order results asc(ending) or desc(ending).
248-
order_by (Optional[TupleOrderBy]): Which field to order results by.
278+
filter: The filter for listing tuples.
279+
size: The size of the result set. Default is None.
280+
last: The last token from a previous response. Default is None.
281+
order: Order results asc(ending) or desc(ending).
282+
order_by: Which field to order results by.
249283
250284
Raises:
251285
PangeaAPIException: If an API Error happens.
@@ -263,13 +297,13 @@ def tuple_list(
263297
)
264298
return self.request.post("v1/tuple/list", TupleListResult, data=input_data.model_dump(exclude_none=True))
265299

266-
def tuple_delete(self, tuples: List[Tuple]) -> PangeaResponse[TupleDeleteResult]:
300+
def tuple_delete(self, tuples: list[Tuple]) -> PangeaResponse[TupleDeleteResult]:
267301
"""Delete tuples.
268302
269303
Delete tuples in the AuthZ Service.
270304
271305
Args:
272-
tuples (List[Tuple]): List of tuples to be deleted.
306+
tuples: Tuples to be deleted.
273307
274308
Raises:
275309
PangeaAPIException: If an API Error happens.
@@ -299,19 +333,19 @@ def check(
299333
resource: Resource,
300334
action: str,
301335
subject: Subject,
302-
debug: Optional[bool] = None,
303-
attributes: Optional[Dict[str, Any]] = None,
336+
debug: bool | None = None,
337+
attributes: dict[str, Any] | None = None,
304338
) -> PangeaResponse[CheckResult]:
305339
"""Perform a check request.
306340
307341
Check if a subject has permission to perform an action on the resource.
308342
309343
Args:
310-
resource (Resource): The resource to check.
311-
action (str): The action to check.
312-
subject (Subject): The subject to check.
313-
debug (Optional[bool]): Setting this value to True will provide a detailed analysis of the check.
314-
attributes (Optional[Dict[str, Any]]): Additional attributes for the check.
344+
resource: The resource to check.
345+
action: The action to check.
346+
subject: The subject to check.
347+
debug: In the event of an allowed check, return a path that granted access.
348+
attributes: Additional attributes for the check.
315349
316350
Raises:
317351
PangeaAPIException: If an API Error happens.
@@ -334,18 +368,18 @@ def check(
334368
return self.request.post("v1/check", CheckResult, data=input_data.model_dump(exclude_none=True))
335369

336370
def list_resources(
337-
self, type: str, action: str, subject: Subject, attributes: Optional[Dict[str, Any]] = None
371+
self, type: str, action: str, subject: Subject, attributes: dict[str, Any] | None = None
338372
) -> PangeaResponse[ListResourcesResult]:
339373
"""List resources.
340374
341375
Given a type, action, and subject, list all the resources in the
342376
type that the subject has access to the action with.
343377
344378
Args:
345-
type (str): The type to filter resources.
346-
action (str): The action to filter resources.
347-
subject (Subject): The subject to filter resources.
348-
attributes (Optional[Dict[str, Any]]): A JSON object of attribute data.
379+
type: The type to filter resources.
380+
action: The action to filter resources.
381+
subject: The subject to filter resources.
382+
attributes: A JSON object of attribute data.
349383
350384
Raises:
351385
PangeaAPIException: If an API Error happens.
@@ -369,17 +403,18 @@ def list_resources(
369403
)
370404

371405
def list_subjects(
372-
self, resource: Resource, action: str, attributes: Optional[Dict[str, Any]] = None
406+
self, resource: Resource, action: str, attributes: dict[str, Any] | None = None, *, debug: bool | None = None
373407
) -> PangeaResponse[ListSubjectsResult]:
374408
"""List subjects.
375409
376410
Given a resource and an action, return the list of subjects who have
377411
access to the action for the given resource.
378412
379413
Args:
380-
resource (Resource): The resource to filter subjects.
381-
action (str): The action to filter subjects.
382-
attributes (Optional[Dict[str, Any]]): A JSON object of attribute data.
414+
resource: The resource to filter subjects.
415+
action: The action to filter subjects.
416+
attributes: A JSON object of attribute data.
417+
debug: Return a path for each found subject.
383418
384419
Raises:
385420
PangeaAPIException: If an API Error happens.
@@ -396,5 +431,5 @@ def list_subjects(
396431
)
397432
"""
398433

399-
input_data = ListSubjectsRequest(resource=resource, action=action, attributes=attributes)
434+
input_data = ListSubjectsRequest(resource=resource, action=action, attributes=attributes, debug=debug)
400435
return self.request.post("v1/list-subjects", ListSubjectsResult, data=input_data.model_dump(exclude_none=True))

0 commit comments

Comments
 (0)