pangea-sdk 3.9.0__py3-none-any.whl → 4.0.0__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.
- pangea/__init__.py +1 -1
- pangea/asyncio/request.py +4 -4
- pangea/asyncio/services/audit.py +30 -11
- pangea/asyncio/services/authn.py +49 -29
- pangea/asyncio/services/authz.py +13 -7
- pangea/asyncio/services/embargo.py +2 -2
- pangea/asyncio/services/file_scan.py +3 -3
- pangea/asyncio/services/intel.py +40 -22
- pangea/asyncio/services/redact.py +5 -3
- pangea/asyncio/services/vault.py +32 -28
- pangea/dump_audit.py +1 -1
- pangea/request.py +8 -5
- pangea/response.py +9 -16
- pangea/services/audit/audit.py +43 -20
- pangea/services/audit/models.py +3 -3
- pangea/services/audit/util.py +3 -3
- pangea/services/authn/authn.py +39 -29
- pangea/services/authn/models.py +9 -4
- pangea/services/authz.py +10 -8
- pangea/services/embargo.py +2 -2
- pangea/services/file_scan.py +2 -2
- pangea/services/intel.py +23 -21
- pangea/services/redact.py +3 -3
- pangea/services/vault/models/common.py +6 -6
- pangea/services/vault/models/symmetric.py +2 -2
- pangea/services/vault/vault.py +28 -28
- pangea/utils.py +1 -18
- pangea/verify_audit.py +267 -83
- {pangea_sdk-3.9.0.dist-info → pangea_sdk-4.0.0.dist-info}/METADATA +10 -9
- pangea_sdk-4.0.0.dist-info/RECORD +46 -0
- {pangea_sdk-3.9.0.dist-info → pangea_sdk-4.0.0.dist-info}/WHEEL +1 -1
- pangea_sdk-3.9.0.dist-info/RECORD +0 -46
pangea/__init__.py
CHANGED
pangea/asyncio/request.py
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
import asyncio
|
5
5
|
import json
|
6
6
|
import time
|
7
|
-
from typing import Dict, List, Optional, Tuple, Type, Union
|
7
|
+
from typing import Dict, List, Optional, Sequence, Tuple, Type, Union
|
8
8
|
|
9
9
|
import aiohttp
|
10
10
|
from aiohttp import FormData
|
@@ -15,7 +15,7 @@ from pangea.request import MultipartResponse, PangeaRequestBase
|
|
15
15
|
from pangea.response import AttachedFile, PangeaResponse, PangeaResponseResult, ResponseStatus, TransferMethod
|
16
16
|
from pangea.utils import default_encoder
|
17
17
|
|
18
|
-
TResult = TypeVar("TResult", bound=PangeaResponseResult
|
18
|
+
TResult = TypeVar("TResult", bound=PangeaResponseResult)
|
19
19
|
|
20
20
|
|
21
21
|
class PangeaRequestAsync(PangeaRequestBase):
|
@@ -160,7 +160,7 @@ class PangeaRequestAsync(PangeaRequestBase):
|
|
160
160
|
if resp.status < 200 or resp.status >= 300:
|
161
161
|
raise pe.PresignedUploadError(f"presigned POST failure: {resp.status}", await resp.text())
|
162
162
|
|
163
|
-
async def put_presigned_url(self, url: str, files:
|
163
|
+
async def put_presigned_url(self, url: str, files: Sequence[Tuple]):
|
164
164
|
# Send put request with file as body
|
165
165
|
resp = await self._http_put(url=url, files=files)
|
166
166
|
self.logger.debug(
|
@@ -275,7 +275,7 @@ class PangeaRequestAsync(PangeaRequestBase):
|
|
275
275
|
async def _http_put(
|
276
276
|
self,
|
277
277
|
url: str,
|
278
|
-
files:
|
278
|
+
files: Sequence[Tuple],
|
279
279
|
headers: Dict = {},
|
280
280
|
) -> aiohttp.ClientResponse:
|
281
281
|
self.logger.debug(
|
pangea/asyncio/services/audit.py
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
from __future__ import annotations
|
4
4
|
|
5
5
|
import datetime
|
6
|
-
from typing import Any, Dict, List, Optional, Sequence, Union
|
6
|
+
from typing import Any, Dict, Iterable, List, Optional, Sequence, Union
|
7
7
|
|
8
8
|
import pangea.exceptions as pexc
|
9
9
|
from pangea.asyncio.services.base import ServiceBaseAsync
|
@@ -203,7 +203,7 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
|
|
203
203
|
|
204
204
|
input = self._get_log_request(event, sign_local=sign_local, verify=verify, verbose=verbose)
|
205
205
|
response: PangeaResponse[LogResult] = await self.request.post(
|
206
|
-
"v1/log", LogResult, data=input.
|
206
|
+
"v1/log", LogResult, data=input.model_dump(exclude_none=True)
|
207
207
|
)
|
208
208
|
if response.success and response.result is not None:
|
209
209
|
self._process_log_result(response.result, verify=verify)
|
@@ -239,7 +239,7 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
|
|
239
239
|
|
240
240
|
input = self._get_log_request(events, sign_local=sign_local, verify=False, verbose=verbose)
|
241
241
|
response: PangeaResponse[LogBulkResult] = await self.request.post(
|
242
|
-
"v2/log", LogBulkResult, data=input.
|
242
|
+
"v2/log", LogBulkResult, data=input.model_dump(exclude_none=True)
|
243
243
|
)
|
244
244
|
if response.success and response.result is not None:
|
245
245
|
for result in response.result.results:
|
@@ -277,7 +277,7 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
|
|
277
277
|
input = self._get_log_request(events, sign_local=sign_local, verify=False, verbose=verbose)
|
278
278
|
try:
|
279
279
|
response: PangeaResponse[LogBulkResult] = await self.request.post(
|
280
|
-
"v2/log_async", LogBulkResult, data=input.
|
280
|
+
"v2/log_async", LogBulkResult, data=input.model_dump(exclude_none=True), poll_result=False
|
281
281
|
)
|
282
282
|
except pexc.AcceptedRequestException as e:
|
283
283
|
return e.response
|
@@ -361,7 +361,7 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
|
|
361
361
|
)
|
362
362
|
|
363
363
|
response: PangeaResponse[SearchOutput] = await self.request.post(
|
364
|
-
"v1/search", SearchOutput, data=input.
|
364
|
+
"v1/search", SearchOutput, data=input.model_dump(exclude_none=True)
|
365
365
|
)
|
366
366
|
if verify_consistency:
|
367
367
|
await self.update_published_roots(response.result) # type: ignore[arg-type]
|
@@ -426,7 +426,7 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
|
|
426
426
|
assert_search_restriction=assert_search_restriction,
|
427
427
|
return_context=return_context,
|
428
428
|
)
|
429
|
-
response = await self.request.post("v1/results", SearchResultOutput, data=input.
|
429
|
+
response = await self.request.post("v1/results", SearchResultOutput, data=input.model_dump(exclude_none=True))
|
430
430
|
if verify_consistency and response.result is not None:
|
431
431
|
await self.update_published_roots(response.result)
|
432
432
|
|
@@ -488,7 +488,7 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
|
|
488
488
|
)
|
489
489
|
try:
|
490
490
|
return await self.request.post(
|
491
|
-
"v1/export", PangeaResponseResult, data=input.
|
491
|
+
"v1/export", PangeaResponseResult, data=input.model_dump(exclude_none=True), poll_result=False
|
492
492
|
)
|
493
493
|
except pexc.AcceptedRequestException as e:
|
494
494
|
return e.response
|
@@ -555,7 +555,7 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
|
|
555
555
|
response = audit.root(tree_size=7)
|
556
556
|
"""
|
557
557
|
input = RootRequest(tree_size=tree_size)
|
558
|
-
return await self.request.post("v1/root", RootResult, data=input.
|
558
|
+
return await self.request.post("v1/root", RootResult, data=input.model_dump(exclude_none=True))
|
559
559
|
|
560
560
|
async def download_results(
|
561
561
|
self,
|
@@ -597,7 +597,7 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
|
|
597
597
|
input = DownloadRequest(
|
598
598
|
request_id=request_id, result_id=result_id, format=format, return_context=return_context
|
599
599
|
)
|
600
|
-
return await self.request.post("v1/download_results", DownloadResult, data=input.
|
600
|
+
return await self.request.post("v1/download_results", DownloadResult, data=input.model_dump(exclude_none=True))
|
601
601
|
|
602
602
|
async def update_published_roots(self, result: SearchResultOutput):
|
603
603
|
"""Fetches series of published root hashes from Arweave
|
@@ -622,12 +622,31 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
|
|
622
622
|
for tree_size in tree_sizes:
|
623
623
|
pub_root = None
|
624
624
|
if tree_size in arweave_roots:
|
625
|
-
pub_root = PublishedRoot(**arweave_roots[tree_size].
|
625
|
+
pub_root = PublishedRoot(**arweave_roots[tree_size].model_dump(exclude_none=True))
|
626
626
|
pub_root.source = RootSource.ARWEAVE
|
627
627
|
elif self.allow_server_roots:
|
628
628
|
resp = await self.root(tree_size=tree_size)
|
629
629
|
if resp.success and resp.result is not None:
|
630
|
-
pub_root = PublishedRoot(**resp.result.data.
|
630
|
+
pub_root = PublishedRoot(**resp.result.data.model_dump(exclude_none=True))
|
631
631
|
pub_root.source = RootSource.PANGEA
|
632
632
|
if pub_root is not None:
|
633
633
|
self.pub_roots[tree_size] = pub_root
|
634
|
+
|
635
|
+
await self.fix_consistency_proofs(tree_sizes)
|
636
|
+
|
637
|
+
async def fix_consistency_proofs(self, tree_sizes: Iterable[int]):
|
638
|
+
# on very rare occasions, the consistency proof in Arweave may be wrong
|
639
|
+
# override it with the proof from pangea (not the root hash, just the proof)
|
640
|
+
for tree_size in tree_sizes:
|
641
|
+
if tree_size not in self.pub_roots or tree_size - 1 not in self.pub_roots:
|
642
|
+
continue
|
643
|
+
|
644
|
+
if self.pub_roots[tree_size].source == RootSource.PANGEA:
|
645
|
+
continue
|
646
|
+
|
647
|
+
if self.verify_consistency_proof(tree_size):
|
648
|
+
continue
|
649
|
+
|
650
|
+
resp = await self.root(tree_size=tree_size)
|
651
|
+
if resp.success and resp.result is not None and resp.result.data is not None:
|
652
|
+
self.pub_roots[tree_size].consistency_proof = resp.result.data.consistency_proof
|
pangea/asyncio/services/authn.py
CHANGED
@@ -96,7 +96,7 @@ class AuthNAsync(ServiceBaseAsync):
|
|
96
96
|
"""
|
97
97
|
input = m.SessionInvalidateRequest(session_id=session_id)
|
98
98
|
return await self.request.post(
|
99
|
-
"v2/session/invalidate", m.SessionInvalidateResult, data=input.
|
99
|
+
"v2/session/invalidate", m.SessionInvalidateResult, data=input.model_dump(exclude_none=True)
|
100
100
|
)
|
101
101
|
|
102
102
|
async def list(
|
@@ -133,7 +133,9 @@ class AuthNAsync(ServiceBaseAsync):
|
|
133
133
|
filter = m.SessionListFilter(**filter)
|
134
134
|
|
135
135
|
input = m.SessionListRequest(filter=filter, last=last, order=order, order_by=order_by, size=size)
|
136
|
-
return await self.request.post(
|
136
|
+
return await self.request.post(
|
137
|
+
"v2/session/list", m.SessionListResults, data=input.model_dump(exclude_none=True)
|
138
|
+
)
|
137
139
|
|
138
140
|
async def logout(self, user_id: str) -> PangeaResponse[m.SessionLogoutResult]:
|
139
141
|
"""
|
@@ -156,7 +158,7 @@ class AuthNAsync(ServiceBaseAsync):
|
|
156
158
|
"""
|
157
159
|
input = m.SessionLogoutRequest(user_id=user_id)
|
158
160
|
return await self.request.post(
|
159
|
-
"v2/session/logout", m.SessionLogoutResult, data=input.
|
161
|
+
"v2/session/logout", m.SessionLogoutResult, data=input.model_dump(exclude_none=True)
|
160
162
|
)
|
161
163
|
|
162
164
|
class ClientAsync(ServiceBaseAsync):
|
@@ -196,7 +198,7 @@ class AuthNAsync(ServiceBaseAsync):
|
|
196
198
|
"""
|
197
199
|
input = m.ClientUserinfoRequest(code=code)
|
198
200
|
return await self.request.post(
|
199
|
-
"v2/client/userinfo", m.ClientUserinfoResult, data=input.
|
201
|
+
"v2/client/userinfo", m.ClientUserinfoResult, data=input.model_dump(exclude_none=True)
|
200
202
|
)
|
201
203
|
|
202
204
|
async def jwks(
|
@@ -253,7 +255,9 @@ class AuthNAsync(ServiceBaseAsync):
|
|
253
255
|
"""
|
254
256
|
input = m.ClientSessionInvalidateRequest(token=token, session_id=session_id)
|
255
257
|
return await self.request.post(
|
256
|
-
"v2/client/session/invalidate",
|
258
|
+
"v2/client/session/invalidate",
|
259
|
+
m.ClientSessionInvalidateResult,
|
260
|
+
data=input.model_dump(exclude_none=True),
|
257
261
|
)
|
258
262
|
|
259
263
|
async def list(
|
@@ -297,7 +301,7 @@ class AuthNAsync(ServiceBaseAsync):
|
|
297
301
|
token=token, filter=filter, last=last, order=order, order_by=order_by, size=size
|
298
302
|
)
|
299
303
|
return await self.request.post(
|
300
|
-
"v2/client/session/list", m.ClientSessionListResults, data=input.
|
304
|
+
"v2/client/session/list", m.ClientSessionListResults, data=input.model_dump(exclude_none=True)
|
301
305
|
)
|
302
306
|
|
303
307
|
async def logout(self, token: str) -> PangeaResponse[m.ClientSessionLogoutResult]:
|
@@ -321,7 +325,7 @@ class AuthNAsync(ServiceBaseAsync):
|
|
321
325
|
"""
|
322
326
|
input = m.ClientSessionLogoutRequest(token=token)
|
323
327
|
return await self.request.post(
|
324
|
-
"v2/client/session/logout", m.ClientSessionLogoutResult, data=input.
|
328
|
+
"v2/client/session/logout", m.ClientSessionLogoutResult, data=input.model_dump(exclude_none=True)
|
325
329
|
)
|
326
330
|
|
327
331
|
async def refresh(
|
@@ -351,7 +355,7 @@ class AuthNAsync(ServiceBaseAsync):
|
|
351
355
|
"""
|
352
356
|
input = m.ClientSessionRefreshRequest(refresh_token=refresh_token, user_token=user_token)
|
353
357
|
return await self.request.post(
|
354
|
-
"v2/client/session/refresh", m.ClientSessionRefreshResult, data=input.
|
358
|
+
"v2/client/session/refresh", m.ClientSessionRefreshResult, data=input.model_dump(exclude_none=True)
|
355
359
|
)
|
356
360
|
|
357
361
|
class PasswordAsync(ServiceBaseAsync):
|
@@ -392,7 +396,7 @@ class AuthNAsync(ServiceBaseAsync):
|
|
392
396
|
"""
|
393
397
|
input = m.ClientPasswordChangeRequest(token=token, old_password=old_password, new_password=new_password)
|
394
398
|
return await self.request.post(
|
395
|
-
"v2/client/password/change", m.ClientPasswordChangeResult, data=input.
|
399
|
+
"v2/client/password/change", m.ClientPasswordChangeResult, data=input.model_dump(exclude_none=True)
|
396
400
|
)
|
397
401
|
|
398
402
|
class TokenAsync(ServiceBaseAsync):
|
@@ -429,7 +433,7 @@ class AuthNAsync(ServiceBaseAsync):
|
|
429
433
|
"""
|
430
434
|
input = m.ClientTokenCheckRequest(token=token)
|
431
435
|
return await self.request.post(
|
432
|
-
"v2/client/token/check", m.ClientTokenCheckResult, data=input.
|
436
|
+
"v2/client/token/check", m.ClientTokenCheckResult, data=input.model_dump(exclude_none=True)
|
433
437
|
)
|
434
438
|
|
435
439
|
class UserAsync(ServiceBaseAsync):
|
@@ -484,7 +488,9 @@ class AuthNAsync(ServiceBaseAsync):
|
|
484
488
|
profile=profile,
|
485
489
|
username=username,
|
486
490
|
)
|
487
|
-
return await self.request.post(
|
491
|
+
return await self.request.post(
|
492
|
+
"v2/user/create", m.UserCreateResult, data=input.model_dump(exclude_none=True)
|
493
|
+
)
|
488
494
|
|
489
495
|
async def delete(
|
490
496
|
self, email: str | None = None, id: str | None = None, *, username: str | None = None
|
@@ -508,7 +514,9 @@ class AuthNAsync(ServiceBaseAsync):
|
|
508
514
|
authn.user.delete(email="example@example.com")
|
509
515
|
"""
|
510
516
|
input = m.UserDeleteRequest(email=email, id=id, username=username)
|
511
|
-
return await self.request.post(
|
517
|
+
return await self.request.post(
|
518
|
+
"v2/user/delete", m.UserDeleteResult, data=input.model_dump(exclude_none=True)
|
519
|
+
)
|
512
520
|
|
513
521
|
async def invite(
|
514
522
|
self,
|
@@ -549,7 +557,9 @@ class AuthNAsync(ServiceBaseAsync):
|
|
549
557
|
callback=callback,
|
550
558
|
state=state,
|
551
559
|
)
|
552
|
-
return await self.request.post(
|
560
|
+
return await self.request.post(
|
561
|
+
"v2/user/invite", m.UserInviteResult, data=input.model_dump(exclude_none=True)
|
562
|
+
)
|
553
563
|
|
554
564
|
async def update(
|
555
565
|
self,
|
@@ -591,7 +601,9 @@ class AuthNAsync(ServiceBaseAsync):
|
|
591
601
|
username=username,
|
592
602
|
)
|
593
603
|
|
594
|
-
return await self.request.post(
|
604
|
+
return await self.request.post(
|
605
|
+
"v2/user/update", m.UserUpdateResult, data=input.model_dump(exclude_none=True)
|
606
|
+
)
|
595
607
|
|
596
608
|
async def list(
|
597
609
|
self,
|
@@ -633,7 +645,7 @@ class AuthNAsync(ServiceBaseAsync):
|
|
633
645
|
order_by=order_by,
|
634
646
|
size=size,
|
635
647
|
)
|
636
|
-
return await self.request.post("v2/user/list", m.UserListResult, data=input.
|
648
|
+
return await self.request.post("v2/user/list", m.UserListResult, data=input.model_dump(exclude_none=True))
|
637
649
|
|
638
650
|
class InvitesAsync(ServiceBaseAsync):
|
639
651
|
service_name = SERVICE_NAME
|
@@ -680,7 +692,7 @@ class AuthNAsync(ServiceBaseAsync):
|
|
680
692
|
|
681
693
|
input = m.UserInviteListRequest(filter=filter, last=last, order=order, order_by=order_by, size=size)
|
682
694
|
return await self.request.post(
|
683
|
-
"v2/user/invite/list", m.UserInviteListResult, data=input.
|
695
|
+
"v2/user/invite/list", m.UserInviteListResult, data=input.model_dump(exclude_none=True)
|
684
696
|
)
|
685
697
|
|
686
698
|
async def delete(self, id: str) -> PangeaResponse[m.UserInviteDeleteResult]:
|
@@ -704,7 +716,7 @@ class AuthNAsync(ServiceBaseAsync):
|
|
704
716
|
"""
|
705
717
|
input = m.UserInviteDeleteRequest(id=id)
|
706
718
|
return await self.request.post(
|
707
|
-
"v2/user/invite/delete", m.UserInviteDeleteResult, data=input.
|
719
|
+
"v2/user/invite/delete", m.UserInviteDeleteResult, data=input.model_dump(exclude_none=True)
|
708
720
|
)
|
709
721
|
|
710
722
|
class AuthenticatorsAsync(ServiceBaseAsync):
|
@@ -754,7 +766,7 @@ class AuthNAsync(ServiceBaseAsync):
|
|
754
766
|
return await self.request.post(
|
755
767
|
"v2/user/authenticators/delete",
|
756
768
|
m.UserAuthenticatorsDeleteResult,
|
757
|
-
data=input.
|
769
|
+
data=input.model_dump(exclude_none=True),
|
758
770
|
)
|
759
771
|
|
760
772
|
async def list(
|
@@ -784,7 +796,9 @@ class AuthNAsync(ServiceBaseAsync):
|
|
784
796
|
"""
|
785
797
|
input = m.UserAuthenticatorsListRequest(email=email, id=id, username=username)
|
786
798
|
return await self.request.post(
|
787
|
-
"v2/user/authenticators/list",
|
799
|
+
"v2/user/authenticators/list",
|
800
|
+
m.UserAuthenticatorsListResult,
|
801
|
+
data=input.model_dump(exclude_none=True),
|
788
802
|
)
|
789
803
|
|
790
804
|
class ProfileAsync(ServiceBaseAsync):
|
@@ -825,7 +839,7 @@ class AuthNAsync(ServiceBaseAsync):
|
|
825
839
|
"""
|
826
840
|
input = m.UserProfileGetRequest(id=id, email=email, username=username)
|
827
841
|
return await self.request.post(
|
828
|
-
"v2/user/profile/get", m.UserProfileGetResult, data=input.
|
842
|
+
"v2/user/profile/get", m.UserProfileGetResult, data=input.model_dump(exclude_none=True)
|
829
843
|
)
|
830
844
|
|
831
845
|
async def update(
|
@@ -869,7 +883,7 @@ class AuthNAsync(ServiceBaseAsync):
|
|
869
883
|
username=username,
|
870
884
|
)
|
871
885
|
return await self.request.post(
|
872
|
-
"v2/user/profile/update", m.UserProfileUpdateResult, data=input.
|
886
|
+
"v2/user/profile/update", m.UserProfileUpdateResult, data=input.model_dump(exclude_none=True)
|
873
887
|
)
|
874
888
|
|
875
889
|
class FlowAsync(ServiceBaseAsync):
|
@@ -905,7 +919,9 @@ class AuthNAsync(ServiceBaseAsync):
|
|
905
919
|
)
|
906
920
|
"""
|
907
921
|
input = m.FlowCompleteRequest(flow_id=flow_id)
|
908
|
-
return await self.request.post(
|
922
|
+
return await self.request.post(
|
923
|
+
"v2/flow/complete", m.FlowCompleteResult, data=input.model_dump(exclude_none=True)
|
924
|
+
)
|
909
925
|
|
910
926
|
async def restart(
|
911
927
|
self, flow_id: str, choice: m.FlowChoice, data: m.FlowRestartData = {}
|
@@ -937,7 +953,9 @@ class AuthNAsync(ServiceBaseAsync):
|
|
937
953
|
"""
|
938
954
|
|
939
955
|
input = m.FlowRestartRequest(flow_id=flow_id, choice=choice, data=data)
|
940
|
-
return await self.request.post(
|
956
|
+
return await self.request.post(
|
957
|
+
"v2/flow/restart", m.FlowRestartResult, data=input.model_dump(exclude_none=True)
|
958
|
+
)
|
941
959
|
|
942
960
|
async def start(
|
943
961
|
self,
|
@@ -976,7 +994,7 @@ class AuthNAsync(ServiceBaseAsync):
|
|
976
994
|
)
|
977
995
|
"""
|
978
996
|
input = m.FlowStartRequest(cb_uri=cb_uri, email=email, flow_types=flow_types, invitation=invitation)
|
979
|
-
return await self.request.post("v2/flow/start", m.FlowStartResult, data=input.
|
997
|
+
return await self.request.post("v2/flow/start", m.FlowStartResult, data=input.model_dump(exclude_none=True))
|
980
998
|
|
981
999
|
async def update(
|
982
1000
|
self, flow_id: str, choice: m.FlowChoice, data: m.FlowUpdateData = {}
|
@@ -1010,7 +1028,9 @@ class AuthNAsync(ServiceBaseAsync):
|
|
1010
1028
|
"""
|
1011
1029
|
|
1012
1030
|
input = m.FlowUpdateRequest(flow_id=flow_id, choice=choice, data=data)
|
1013
|
-
return await self.request.post(
|
1031
|
+
return await self.request.post(
|
1032
|
+
"v2/flow/update", m.FlowUpdateResult, data=input.model_dump(exclude_none=True)
|
1033
|
+
)
|
1014
1034
|
|
1015
1035
|
class AgreementsAsync(ServiceBaseAsync):
|
1016
1036
|
service_name = SERVICE_NAME
|
@@ -1054,7 +1074,7 @@ class AuthNAsync(ServiceBaseAsync):
|
|
1054
1074
|
|
1055
1075
|
input = m.AgreementCreateRequest(type=type, name=name, text=text, active=active)
|
1056
1076
|
return await self.request.post(
|
1057
|
-
"v2/agreements/create", m.AgreementCreateResult, data=input.
|
1077
|
+
"v2/agreements/create", m.AgreementCreateResult, data=input.model_dump(exclude_none=True)
|
1058
1078
|
)
|
1059
1079
|
|
1060
1080
|
async def delete(self, type: m.AgreementType, id: str) -> PangeaResponse[m.AgreementDeleteResult]:
|
@@ -1081,7 +1101,7 @@ class AuthNAsync(ServiceBaseAsync):
|
|
1081
1101
|
|
1082
1102
|
input = m.AgreementDeleteRequest(type=type, id=id)
|
1083
1103
|
return await self.request.post(
|
1084
|
-
"v2/agreements/delete", m.AgreementDeleteResult, data=input.
|
1104
|
+
"v2/agreements/delete", m.AgreementDeleteResult, data=input.model_dump(exclude_none=True)
|
1085
1105
|
)
|
1086
1106
|
|
1087
1107
|
async def list(
|
@@ -1119,7 +1139,7 @@ class AuthNAsync(ServiceBaseAsync):
|
|
1119
1139
|
|
1120
1140
|
input = m.AgreementListRequest(filter=filter, last=last, order=order, order_by=order_by, size=size)
|
1121
1141
|
return await self.request.post(
|
1122
|
-
"v2/agreements/list", m.AgreementListResult, data=input.
|
1142
|
+
"v2/agreements/list", m.AgreementListResult, data=input.model_dump(exclude_none=True)
|
1123
1143
|
)
|
1124
1144
|
|
1125
1145
|
async def update(
|
@@ -1160,5 +1180,5 @@ class AuthNAsync(ServiceBaseAsync):
|
|
1160
1180
|
|
1161
1181
|
input = m.AgreementUpdateRequest(type=type, id=id, name=name, text=text, active=active)
|
1162
1182
|
return await self.request.post(
|
1163
|
-
"v2/agreements/update", m.AgreementUpdateResult, data=input.
|
1183
|
+
"v2/agreements/update", m.AgreementUpdateResult, data=input.model_dump(exclude_none=True)
|
1164
1184
|
)
|
pangea/asyncio/services/authz.py
CHANGED
@@ -82,7 +82,9 @@ class AuthZAsync(ServiceBaseAsync):
|
|
82
82
|
"""
|
83
83
|
|
84
84
|
input_data = TupleCreateRequest(tuples=tuples)
|
85
|
-
return await self.request.post(
|
85
|
+
return await self.request.post(
|
86
|
+
"v1/tuple/create", TupleCreateResult, data=input_data.model_dump(exclude_none=True)
|
87
|
+
)
|
86
88
|
|
87
89
|
async def tuple_list(
|
88
90
|
self,
|
@@ -117,9 +119,9 @@ class AuthZAsync(ServiceBaseAsync):
|
|
117
119
|
await authz.tuple_list(TupleListFilter(subject_type="user", subject_id="user_1"))
|
118
120
|
"""
|
119
121
|
input_data = TupleListRequest(
|
120
|
-
filter=filter.
|
122
|
+
filter=filter.model_dump(exclude_none=True), size=size, last=last, order=order, order_by=order_by
|
121
123
|
)
|
122
|
-
return await self.request.post("v1/tuple/list", TupleListResult, data=input_data.
|
124
|
+
return await self.request.post("v1/tuple/list", TupleListResult, data=input_data.model_dump(exclude_none=True))
|
123
125
|
|
124
126
|
async def tuple_delete(self, tuples: List[Tuple]) -> PangeaResponse[TupleDeleteResult]:
|
125
127
|
"""Delete tuples.
|
@@ -150,7 +152,9 @@ class AuthZAsync(ServiceBaseAsync):
|
|
150
152
|
"""
|
151
153
|
|
152
154
|
input_data = TupleDeleteRequest(tuples=tuples)
|
153
|
-
return await self.request.post(
|
155
|
+
return await self.request.post(
|
156
|
+
"v1/tuple/delete", TupleDeleteResult, data=input_data.model_dump(exclude_none=True)
|
157
|
+
)
|
154
158
|
|
155
159
|
async def check(
|
156
160
|
self,
|
@@ -189,7 +193,7 @@ class AuthZAsync(ServiceBaseAsync):
|
|
189
193
|
"""
|
190
194
|
|
191
195
|
input_data = CheckRequest(resource=resource, action=action, subject=subject, debug=debug, attributes=attributes)
|
192
|
-
return await self.request.post("v1/check", CheckResult, data=input_data.
|
196
|
+
return await self.request.post("v1/check", CheckResult, data=input_data.model_dump(exclude_none=True))
|
193
197
|
|
194
198
|
async def list_resources(self, type: str, action: str, subject: Subject) -> PangeaResponse[ListResourcesResult]:
|
195
199
|
"""List resources.
|
@@ -220,7 +224,7 @@ class AuthZAsync(ServiceBaseAsync):
|
|
220
224
|
|
221
225
|
input_data = ListResourcesRequest(type=type, action=action, subject=subject)
|
222
226
|
return await self.request.post(
|
223
|
-
"v1/list-resources", ListResourcesResult, data=input_data.
|
227
|
+
"v1/list-resources", ListResourcesResult, data=input_data.model_dump(exclude_none=True)
|
224
228
|
)
|
225
229
|
|
226
230
|
async def list_subjects(self, resource: Resource, action: str) -> PangeaResponse[ListSubjectsResult]:
|
@@ -249,4 +253,6 @@ class AuthZAsync(ServiceBaseAsync):
|
|
249
253
|
"""
|
250
254
|
|
251
255
|
input_data = ListSubjectsRequest(resource=resource, action=action)
|
252
|
-
return await self.request.post(
|
256
|
+
return await self.request.post(
|
257
|
+
"v1/list-subjects", ListSubjectsResult, data=input_data.model_dump(exclude_none=True)
|
258
|
+
)
|
@@ -57,7 +57,7 @@ class EmbargoAsync(ServiceBaseAsync):
|
|
57
57
|
response = embargo.ip_check("190.6.64.94")
|
58
58
|
"""
|
59
59
|
input = e.IPCheckRequest(ip=ip)
|
60
|
-
return await self.request.post("v1/ip/check", e.EmbargoResult, data=input.
|
60
|
+
return await self.request.post("v1/ip/check", e.EmbargoResult, data=input.model_dump())
|
61
61
|
|
62
62
|
async def iso_check(self, iso_code: str) -> PangeaResponse[e.EmbargoResult]:
|
63
63
|
"""
|
@@ -84,4 +84,4 @@ class EmbargoAsync(ServiceBaseAsync):
|
|
84
84
|
response = embargo.iso_check("CU")
|
85
85
|
"""
|
86
86
|
input = e.ISOCheckRequest(iso_code=iso_code)
|
87
|
-
return await self.request.post("v1/iso/check", result_class=e.EmbargoResult, data=input.
|
87
|
+
return await self.request.post("v1/iso/check", result_class=e.EmbargoResult, data=input.model_dump())
|
@@ -109,7 +109,7 @@ class FileScanAsync(ServiceBaseAsync):
|
|
109
109
|
transfer_method=transfer_method,
|
110
110
|
source_url=source_url,
|
111
111
|
)
|
112
|
-
data = input.
|
112
|
+
data = input.model_dump(exclude_none=True)
|
113
113
|
return await self.request.post("v1/scan", m.FileScanResult, data=data, files=files, poll_result=sync_call)
|
114
114
|
|
115
115
|
async def request_upload_url(
|
@@ -131,7 +131,7 @@ class FileScanAsync(ServiceBaseAsync):
|
|
131
131
|
input.sha256 = params.sha256_hex
|
132
132
|
input.size = params.size
|
133
133
|
|
134
|
-
data = input.
|
134
|
+
data = input.model_dump(exclude_none=True)
|
135
135
|
return await self.request.request_presigned_url("v1/scan", m.FileScanResult, data=data)
|
136
136
|
|
137
137
|
|
@@ -154,7 +154,7 @@ class FileUploaderAsync:
|
|
154
154
|
) -> None:
|
155
155
|
if transfer_method == TransferMethod.PUT_URL:
|
156
156
|
files = [("file", ("filename", file, "application/octet-stream"))]
|
157
|
-
await self._request.put_presigned_url(url=url, files=files)
|
157
|
+
await self._request.put_presigned_url(url=url, files=files)
|
158
158
|
elif transfer_method == TransferMethod.POST_URL:
|
159
159
|
files = [("file", ("filename", file, "application/octet-stream"))]
|
160
160
|
await self._request.post_presigned_url(url=url, data=file_details, files=files) # type: ignore[arg-type]
|