pangea-sdk 6.2.0b1__py3-none-any.whl → 6.2.0b2__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 +9 -1
- pangea/asyncio/__init__.py +1 -0
- pangea/asyncio/file_uploader.py +4 -2
- pangea/asyncio/request.py +51 -21
- pangea/asyncio/services/__init__.py +2 -0
- pangea/asyncio/services/ai_guard.py +91 -2
- pangea/asyncio/services/audit.py +14 -8
- pangea/asyncio/services/authn.py +33 -23
- pangea/asyncio/services/authz.py +6 -6
- pangea/asyncio/services/base.py +4 -0
- pangea/asyncio/services/file_scan.py +8 -2
- pangea/asyncio/services/intel.py +6 -2
- pangea/asyncio/services/prompt_guard.py +112 -2
- pangea/asyncio/services/redact.py +7 -3
- pangea/asyncio/services/sanitize.py +5 -1
- pangea/asyncio/services/share.py +5 -1
- pangea/asyncio/services/vault.py +19 -15
- pangea/audit_logger.py +3 -1
- pangea/deep_verify.py +13 -13
- pangea/deprecated.py +1 -1
- pangea/dump_audit.py +2 -3
- pangea/exceptions.py +8 -5
- pangea/file_uploader.py +4 -0
- pangea/request.py +58 -41
- pangea/response.py +15 -12
- pangea/services/__init__.py +2 -0
- pangea/services/ai_guard.py +497 -16
- pangea/services/audit/audit.py +15 -13
- pangea/services/audit/models.py +4 -0
- pangea/services/audit/signing.py +1 -1
- pangea/services/audit/util.py +10 -10
- pangea/services/authn/authn.py +33 -23
- pangea/services/authn/models.py +3 -0
- pangea/services/authz.py +10 -6
- pangea/services/base.py +5 -1
- pangea/services/embargo.py +6 -0
- pangea/services/file_scan.py +8 -2
- pangea/services/intel.py +4 -0
- pangea/services/management.py +8 -8
- pangea/services/prompt_guard.py +193 -2
- pangea/services/redact.py +7 -3
- pangea/services/sanitize.py +5 -1
- pangea/services/share/share.py +13 -7
- pangea/services/vault/models/asymmetric.py +4 -0
- pangea/services/vault/models/common.py +4 -0
- pangea/services/vault/models/symmetric.py +4 -0
- pangea/services/vault/vault.py +17 -19
- pangea/tools.py +13 -9
- pangea/utils.py +3 -5
- pangea/verify_audit.py +23 -27
- {pangea_sdk-6.2.0b1.dist-info → pangea_sdk-6.2.0b2.dist-info}/METADATA +6 -6
- pangea_sdk-6.2.0b2.dist-info/RECORD +62 -0
- {pangea_sdk-6.2.0b1.dist-info → pangea_sdk-6.2.0b2.dist-info}/WHEEL +1 -1
- pangea_sdk-6.2.0b1.dist-info/RECORD +0 -62
pangea/services/prompt_guard.py
CHANGED
@@ -1,9 +1,12 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
-
from
|
3
|
+
from collections.abc import Mapping
|
4
|
+
from typing import TYPE_CHECKING, Annotated, Literal, Optional
|
5
|
+
|
6
|
+
from pydantic import BaseModel, Field
|
4
7
|
|
5
8
|
from pangea.config import PangeaConfig
|
6
|
-
from pangea.response import APIRequestModel, APIResponseModel, PangeaResponse, PangeaResponseResult
|
9
|
+
from pangea.response import APIRequestModel, APIResponseModel, PangeaDateTime, PangeaResponse, PangeaResponseResult
|
7
10
|
from pangea.services.base import ServiceBase
|
8
11
|
|
9
12
|
if TYPE_CHECKING:
|
@@ -46,6 +49,92 @@ class GuardResult(PangeaResponseResult):
|
|
46
49
|
"""List of classification results with labels and confidence scores"""
|
47
50
|
|
48
51
|
|
52
|
+
class Areas(BaseModel):
|
53
|
+
malicious_prompt: Optional[bool] = None
|
54
|
+
benign_prompt: Optional[bool] = None
|
55
|
+
|
56
|
+
|
57
|
+
class AuditDataActivityConfig(BaseModel):
|
58
|
+
enabled: bool
|
59
|
+
audit_service_config_id: str
|
60
|
+
areas: Areas
|
61
|
+
|
62
|
+
|
63
|
+
class ServiceConfig(BaseModel):
|
64
|
+
id: Optional[str] = None
|
65
|
+
version: Optional[str] = None
|
66
|
+
analyzers: Optional[dict[str, bool]] = None
|
67
|
+
malicious_detection_threshold: Annotated[Optional[float], Field(ge=0.0, le=1.0)] = None
|
68
|
+
benign_detection_threshold: Annotated[Optional[float], Field(ge=0.0, le=1.0)] = None
|
69
|
+
audit_data_activity: Optional[AuditDataActivityConfig] = None
|
70
|
+
|
71
|
+
|
72
|
+
class ServiceConfigFilter(BaseModel):
|
73
|
+
id: Optional[str] = None
|
74
|
+
"""
|
75
|
+
Only records where id equals this value.
|
76
|
+
"""
|
77
|
+
id__contains: Optional[list[str]] = None
|
78
|
+
"""
|
79
|
+
Only records where id includes each substring.
|
80
|
+
"""
|
81
|
+
id__in: Optional[list[str]] = None
|
82
|
+
"""
|
83
|
+
Only records where id equals one of the provided substrings.
|
84
|
+
"""
|
85
|
+
created_at: Optional[PangeaDateTime] = None
|
86
|
+
"""
|
87
|
+
Only records where created_at equals this value.
|
88
|
+
"""
|
89
|
+
created_at__gt: Optional[PangeaDateTime] = None
|
90
|
+
"""
|
91
|
+
Only records where created_at is greater than this value.
|
92
|
+
"""
|
93
|
+
created_at__gte: Optional[PangeaDateTime] = None
|
94
|
+
"""
|
95
|
+
Only records where created_at is greater than or equal to this value.
|
96
|
+
"""
|
97
|
+
created_at__lt: Optional[PangeaDateTime] = None
|
98
|
+
"""
|
99
|
+
Only records where created_at is less than this value.
|
100
|
+
"""
|
101
|
+
created_at__lte: Optional[PangeaDateTime] = None
|
102
|
+
"""
|
103
|
+
Only records where created_at is less than or equal to this value.
|
104
|
+
"""
|
105
|
+
updated_at: Optional[PangeaDateTime] = None
|
106
|
+
"""
|
107
|
+
Only records where updated_at equals this value.
|
108
|
+
"""
|
109
|
+
updated_at__gt: Optional[PangeaDateTime] = None
|
110
|
+
"""
|
111
|
+
Only records where updated_at is greater than this value.
|
112
|
+
"""
|
113
|
+
updated_at__gte: Optional[PangeaDateTime] = None
|
114
|
+
"""
|
115
|
+
Only records where updated_at is greater than or equal to this value.
|
116
|
+
"""
|
117
|
+
updated_at__lt: Optional[PangeaDateTime] = None
|
118
|
+
"""
|
119
|
+
Only records where updated_at is less than this value.
|
120
|
+
"""
|
121
|
+
updated_at__lte: Optional[PangeaDateTime] = None
|
122
|
+
"""
|
123
|
+
Only records where updated_at is less than or equal to this value.
|
124
|
+
"""
|
125
|
+
|
126
|
+
|
127
|
+
class ServiceConfigsPage(PangeaResponseResult):
|
128
|
+
count: Optional[int] = None
|
129
|
+
"""The total number of service configs matched by the list request."""
|
130
|
+
last: Optional[str] = None
|
131
|
+
"""
|
132
|
+
Used to fetch the next page of the current listing when provided in a
|
133
|
+
repeated request's last parameter.
|
134
|
+
"""
|
135
|
+
items: Optional[list[ServiceConfig]] = None
|
136
|
+
|
137
|
+
|
49
138
|
class PromptGuard(ServiceBase):
|
50
139
|
"""Prompt Guard service client.
|
51
140
|
|
@@ -116,3 +205,105 @@ class PromptGuard(ServiceBase):
|
|
116
205
|
GuardResult,
|
117
206
|
data={"messages": messages, "analyzers": analyzers, "classify": classify},
|
118
207
|
)
|
208
|
+
|
209
|
+
def get_service_config(
|
210
|
+
self,
|
211
|
+
*,
|
212
|
+
id: str | None = None,
|
213
|
+
version: str | None = None,
|
214
|
+
analyzers: Mapping[str, bool] | None = None,
|
215
|
+
malicious_detection_threshold: float | None = None,
|
216
|
+
benign_detection_threshold: float | None = None,
|
217
|
+
audit_data_activity: AuditDataActivityConfig | None = None,
|
218
|
+
) -> PangeaResponse[PangeaResponseResult]:
|
219
|
+
"""
|
220
|
+
OperationId: prompt_guard_post_v1beta_config
|
221
|
+
"""
|
222
|
+
return self.request.post(
|
223
|
+
"v1beta/config",
|
224
|
+
data={
|
225
|
+
"id": id,
|
226
|
+
"version": version,
|
227
|
+
"analyzers": analyzers,
|
228
|
+
"malicious_detection_threshold": malicious_detection_threshold,
|
229
|
+
"benign_detection_threshold": benign_detection_threshold,
|
230
|
+
"audit_data_activity": audit_data_activity,
|
231
|
+
},
|
232
|
+
result_class=PangeaResponseResult,
|
233
|
+
)
|
234
|
+
|
235
|
+
def create_service_config(
|
236
|
+
self,
|
237
|
+
*,
|
238
|
+
id: str | None = None,
|
239
|
+
version: str | None = None,
|
240
|
+
analyzers: Mapping[str, bool] | None = None,
|
241
|
+
malicious_detection_threshold: float | None = None,
|
242
|
+
benign_detection_threshold: float | None = None,
|
243
|
+
audit_data_activity: AuditDataActivityConfig | None = None,
|
244
|
+
) -> PangeaResponse[PangeaResponseResult]:
|
245
|
+
"""
|
246
|
+
OperationId: prompt_guard_post_v1beta_config_create
|
247
|
+
"""
|
248
|
+
return self.request.post(
|
249
|
+
"v1beta/config/create",
|
250
|
+
data={
|
251
|
+
"id": id,
|
252
|
+
"version": version,
|
253
|
+
"analyzers": analyzers,
|
254
|
+
"malicious_detection_threshold": malicious_detection_threshold,
|
255
|
+
"benign_detection_threshold": benign_detection_threshold,
|
256
|
+
"audit_data_activity": audit_data_activity,
|
257
|
+
},
|
258
|
+
result_class=PangeaResponseResult,
|
259
|
+
)
|
260
|
+
|
261
|
+
def update_service_config(
|
262
|
+
self,
|
263
|
+
*,
|
264
|
+
id: str | None = None,
|
265
|
+
version: str | None = None,
|
266
|
+
analyzers: Mapping[str, bool] | None = None,
|
267
|
+
malicious_detection_threshold: float | None = None,
|
268
|
+
benign_detection_threshold: float | None = None,
|
269
|
+
audit_data_activity: AuditDataActivityConfig | None = None,
|
270
|
+
) -> PangeaResponse[PangeaResponseResult]:
|
271
|
+
"""
|
272
|
+
OperationId: prompt_guard_post_v1beta_config_update
|
273
|
+
"""
|
274
|
+
return self.request.post(
|
275
|
+
"v1beta/config/update",
|
276
|
+
data={
|
277
|
+
"id": id,
|
278
|
+
"version": version,
|
279
|
+
"analyzers": analyzers,
|
280
|
+
"malicious_detection_threshold": malicious_detection_threshold,
|
281
|
+
"benign_detection_threshold": benign_detection_threshold,
|
282
|
+
"audit_data_activity": audit_data_activity,
|
283
|
+
},
|
284
|
+
result_class=PangeaResponseResult,
|
285
|
+
)
|
286
|
+
|
287
|
+
def delete_service_config(self, id: str) -> PangeaResponse[PangeaResponseResult]:
|
288
|
+
"""
|
289
|
+
OperationId: prompt_guard_post_v1beta_config_delete
|
290
|
+
"""
|
291
|
+
return self.request.post("v1beta/config/delete", data={"id": id}, result_class=PangeaResponseResult)
|
292
|
+
|
293
|
+
def list_service_configs(
|
294
|
+
self,
|
295
|
+
*,
|
296
|
+
filter: ServiceConfigFilter | None = None,
|
297
|
+
last: str | None = None,
|
298
|
+
order: Literal["asc", "desc"] | None = None,
|
299
|
+
order_by: Literal["id", "created_at", "updated_at"] | None = None,
|
300
|
+
size: int | None = None,
|
301
|
+
) -> PangeaResponse[ServiceConfigsPage]:
|
302
|
+
"""
|
303
|
+
OperationId: prompt_guard_post_v1beta_config_list
|
304
|
+
"""
|
305
|
+
return self.request.post(
|
306
|
+
"v1beta/config/list",
|
307
|
+
data={"filter": filter, "last": last, "order": order, "order_by": order_by, "size": size},
|
308
|
+
result_class=ServiceConfigsPage,
|
309
|
+
)
|
pangea/services/redact.py
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
# Copyright 2022 Pangea Cyber Corporation
|
2
2
|
# Author: Pangea Cyber Corporation
|
3
|
+
|
4
|
+
# TODO: Use `list` instead of `List`.
|
5
|
+
# ruff: noqa: UP006, UP035
|
6
|
+
|
3
7
|
from __future__ import annotations
|
4
8
|
|
5
9
|
import enum
|
@@ -481,7 +485,7 @@ class Redact(ServiceBase):
|
|
481
485
|
Returns:
|
482
486
|
Pangea Response with redacted text in the response.result property,
|
483
487
|
available response fields can be found in our
|
484
|
-
[API Documentation](https://pangea.cloud/docs/api/redact#redact).
|
488
|
+
[API Documentation](https://pangea.cloud/docs/api/redact#redact-post).
|
485
489
|
|
486
490
|
Examples:
|
487
491
|
response = redact.redact(text="Jenny Jenny... 555-867-5309")
|
@@ -540,7 +544,7 @@ class Redact(ServiceBase):
|
|
540
544
|
Returns:
|
541
545
|
Pangea Response with redacted data in the response.result field,
|
542
546
|
available response fields can be found in our
|
543
|
-
[API Documentation](https://pangea.cloud/docs/api/redact#redact-structured)
|
547
|
+
[API Documentation](https://pangea.cloud/docs/api/redact#redact-structured-post)
|
544
548
|
|
545
549
|
Examples:
|
546
550
|
data = {
|
@@ -583,7 +587,7 @@ class Redact(ServiceBase):
|
|
583
587
|
Returns:
|
584
588
|
Pangea Response with redacted data in the response.result field,
|
585
589
|
available response fields can be found in our
|
586
|
-
[API Documentation](https://pangea.cloud/docs/api/redact#unredact)
|
590
|
+
[API Documentation](https://pangea.cloud/docs/api/redact#unredact-post)
|
587
591
|
"""
|
588
592
|
input = UnredactRequest(redacted_data=redacted_data, fpe_context=fpe_context)
|
589
593
|
return self.request.post("v1/unredact", UnredactResult, data=input.model_dump(exclude_none=True))
|
pangea/services/sanitize.py
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
# Copyright 2022 Pangea Cyber Corporation
|
2
2
|
# Author: Pangea Cyber Corporation
|
3
|
+
|
4
|
+
# TODO: Use `list` instead of `List`.
|
5
|
+
# ruff: noqa: UP006, UP035
|
6
|
+
|
3
7
|
from __future__ import annotations
|
4
8
|
|
5
9
|
import io
|
@@ -267,7 +271,7 @@ class Sanitize(ServiceBase):
|
|
267
271
|
files: Optional[List[Tuple]] = None
|
268
272
|
if file or file_path:
|
269
273
|
if file_path:
|
270
|
-
file = open(file_path, "rb")
|
274
|
+
file = open(file_path, "rb") # noqa: SIM115
|
271
275
|
if (
|
272
276
|
transfer_method == TransferMethod.POST_URL
|
273
277
|
and file
|
pangea/services/share/share.py
CHANGED
@@ -1,10 +1,16 @@
|
|
1
1
|
# Copyright 2022 Pangea Cyber Corporation
|
2
2
|
# Author: Pangea Cyber Corporation
|
3
|
+
|
4
|
+
# TODO: Use `list` instead of `List`.
|
5
|
+
# ruff: noqa: UP006, UP035
|
6
|
+
|
3
7
|
from __future__ import annotations
|
4
8
|
|
5
9
|
import enum
|
6
10
|
import io
|
7
|
-
from typing import Dict, List,
|
11
|
+
from typing import Dict, List, Optional, Tuple, Union
|
12
|
+
|
13
|
+
from pydantic import RootModel
|
8
14
|
|
9
15
|
from pangea.config import PangeaConfig
|
10
16
|
from pangea.response import APIRequestModel, PangeaResponse, PangeaResponseResult, TransferMethod
|
@@ -12,8 +18,8 @@ from pangea.services.base import ServiceBase
|
|
12
18
|
from pangea.services.share.file_format import FileFormat
|
13
19
|
from pangea.utils import get_file_size, get_file_upload_params
|
14
20
|
|
15
|
-
Metadata =
|
16
|
-
Tags =
|
21
|
+
Metadata = RootModel[dict[str, str]]
|
22
|
+
Tags = RootModel[list[str]]
|
17
23
|
|
18
24
|
|
19
25
|
class ItemOrder(str, enum.Enum):
|
@@ -916,10 +922,10 @@ class Share(ServiceBase):
|
|
916
922
|
|
917
923
|
def get_archive(
|
918
924
|
self,
|
919
|
-
ids:
|
920
|
-
format:
|
921
|
-
transfer_method:
|
922
|
-
bucket_id:
|
925
|
+
ids: list[str],
|
926
|
+
format: ArchiveFormat | None = None,
|
927
|
+
transfer_method: TransferMethod | None = None,
|
928
|
+
bucket_id: str | None = None,
|
923
929
|
) -> PangeaResponse[GetArchiveResult]:
|
924
930
|
"""
|
925
931
|
Get archive
|
pangea/services/vault/vault.py
CHANGED
@@ -2,10 +2,9 @@
|
|
2
2
|
# Author: Pangea Cyber Corporation
|
3
3
|
from __future__ import annotations
|
4
4
|
|
5
|
-
from typing import TYPE_CHECKING,
|
5
|
+
from typing import TYPE_CHECKING, Annotated, Any, Literal, Optional, Union, cast, overload
|
6
6
|
|
7
7
|
from pydantic import Field, TypeAdapter
|
8
|
-
from typing_extensions import Annotated
|
9
8
|
|
10
9
|
from pangea.response import PangeaResponse, PangeaResponseResult
|
11
10
|
from pangea.services.base import ServiceBase
|
@@ -34,7 +33,6 @@ from pangea.services.vault.models.common import (
|
|
34
33
|
EncryptTransformRequest,
|
35
34
|
EncryptTransformResult,
|
36
35
|
ExportEncryptionAlgorithm,
|
37
|
-
ExportEncryptionType,
|
38
36
|
ExportRequest,
|
39
37
|
ExportResult,
|
40
38
|
Folder,
|
@@ -98,7 +96,7 @@ vault_item_adapter: TypeAdapter[VaultItem] = TypeAdapter(VaultItem)
|
|
98
96
|
|
99
97
|
|
100
98
|
class GetBulkResponse(PangeaResponseResult):
|
101
|
-
items:
|
99
|
+
items: list[VaultItem]
|
102
100
|
|
103
101
|
|
104
102
|
class Vault(ServiceBase):
|
@@ -164,7 +162,7 @@ class Vault(ServiceBase):
|
|
164
162
|
Returns:
|
165
163
|
A PangeaResponse where the id of the deleted secret or key
|
166
164
|
is returned in the response.result field.
|
167
|
-
Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault
|
165
|
+
Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault/v1-general#/v1/delete-post).
|
168
166
|
|
169
167
|
Raises:
|
170
168
|
PangeaAPIException: If an API Error happens
|
@@ -197,7 +195,7 @@ class Vault(ServiceBase):
|
|
197
195
|
Returns:
|
198
196
|
A PangeaResponse where the secret or key
|
199
197
|
is returned in the response.result field.
|
200
|
-
Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault
|
198
|
+
Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault/v1-general#/v1/get-post).
|
201
199
|
|
202
200
|
Raises:
|
203
201
|
PangeaAPIException: If an API Error happens
|
@@ -285,7 +283,7 @@ class Vault(ServiceBase):
|
|
285
283
|
Returns:
|
286
284
|
A PangeaResponse where a list of secrets or keys
|
287
285
|
is returned in the response.result field.
|
288
|
-
Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault
|
286
|
+
Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault/v1-general#/v1/list-post).
|
289
287
|
|
290
288
|
Examples:
|
291
289
|
response = vault.list(
|
@@ -344,7 +342,7 @@ class Vault(ServiceBase):
|
|
344
342
|
Returns:
|
345
343
|
A PangeaResponse where the item ID is returned in the
|
346
344
|
response.result field. Available response fields can be found in our
|
347
|
-
[API documentation](https://pangea.cloud/docs/api/vault
|
345
|
+
[API documentation](https://pangea.cloud/docs/api/vault/v1-general#/v1/update-post).
|
348
346
|
|
349
347
|
Raises:
|
350
348
|
PangeaAPIException: If an API Error happens
|
@@ -1679,7 +1677,7 @@ class Vault(ServiceBase):
|
|
1679
1677
|
Returns:
|
1680
1678
|
A PangeaResponse where the encrypted message in base64 is returned
|
1681
1679
|
in the response.result field. Available response fields can be found
|
1682
|
-
in our [API documentation](https://pangea.cloud/docs/api/vault
|
1680
|
+
in our [API documentation](https://pangea.cloud/docs/api/vault/v1-keys#/v1/key/encrypt-post).
|
1683
1681
|
|
1684
1682
|
Raises:
|
1685
1683
|
PangeaAPIException: If an API Error happens
|
@@ -1715,7 +1713,7 @@ class Vault(ServiceBase):
|
|
1715
1713
|
|
1716
1714
|
Returns:
|
1717
1715
|
A PangeaResponse where the decrypted message in base64 is returned
|
1718
|
-
in the response.result field. Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault
|
1716
|
+
in the response.result field. Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault/v1-keys#/v1/key/decrypt-post).
|
1719
1717
|
|
1720
1718
|
Raises:
|
1721
1719
|
PangeaAPIException: If an API Error happens
|
@@ -1749,7 +1747,7 @@ class Vault(ServiceBase):
|
|
1749
1747
|
Returns:
|
1750
1748
|
A PangeaResponse where the signature of the message in base64 is
|
1751
1749
|
returned in the response.result field. Available response fields can
|
1752
|
-
be found in our [API documentation](https://pangea.cloud/docs/api/vault
|
1750
|
+
be found in our [API documentation](https://pangea.cloud/docs/api/vault/v1-keys#/v1/key/sign-post).
|
1753
1751
|
|
1754
1752
|
Raises:
|
1755
1753
|
PangeaAPIException: If an API Error happens
|
@@ -1785,7 +1783,7 @@ class Vault(ServiceBase):
|
|
1785
1783
|
Returns:
|
1786
1784
|
A PangeaResponse where the signature is valid
|
1787
1785
|
is returned in the response.result field.
|
1788
|
-
Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault
|
1786
|
+
Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault/v1-keys#/v1/key/verify-post).
|
1789
1787
|
|
1790
1788
|
Examples:
|
1791
1789
|
response = vault.verify(
|
@@ -1823,7 +1821,7 @@ class Vault(ServiceBase):
|
|
1823
1821
|
Returns:
|
1824
1822
|
A PangeaResponse where the signature is valid
|
1825
1823
|
is returned in the response.result field.
|
1826
|
-
Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault
|
1824
|
+
Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/vault/v1-jwt#/v1/key/verify/jwt-post).
|
1827
1825
|
|
1828
1826
|
Examples:
|
1829
1827
|
response = vault.jwt_verify(jws="ewogICJhbGciO...")
|
@@ -1848,7 +1846,7 @@ class Vault(ServiceBase):
|
|
1848
1846
|
Returns:
|
1849
1847
|
A PangeaResponse where the signed JSON Web Token (JWS) is returned
|
1850
1848
|
in the response.result field. Available response fields can be found
|
1851
|
-
in our [API documentation](https://pangea.cloud/docs/api/vault
|
1849
|
+
in our [API documentation](https://pangea.cloud/docs/api/vault/v1-jwt#/v1/key/sign/jwt-post).
|
1852
1850
|
|
1853
1851
|
Examples:
|
1854
1852
|
response = vault.jwt_sign(
|
@@ -1878,7 +1876,7 @@ class Vault(ServiceBase):
|
|
1878
1876
|
Returns:
|
1879
1877
|
A PangeaResponse where the JSON Web Key Set (JWKS) object is
|
1880
1878
|
returned in the response.result field. Available response fields can
|
1881
|
-
be found in our [API documentation](https://pangea.cloud/docs/api/vault
|
1879
|
+
be found in our [API documentation](https://pangea.cloud/docs/api/vault/v1-jwt#/v1/get/jwk-post).
|
1882
1880
|
|
1883
1881
|
Examples:
|
1884
1882
|
response = vault.jwk_get("pvi_p6g5i3gtbvqvc3u6zugab6qs6r63tqf5")
|
@@ -1910,7 +1908,7 @@ class Vault(ServiceBase):
|
|
1910
1908
|
Returns:
|
1911
1909
|
A PangeaResponse where the state change object is returned in the
|
1912
1910
|
response.result field. Available response fields can be found in our
|
1913
|
-
[API documentation](https://pangea.cloud/docs/api/vault
|
1911
|
+
[API documentation](https://pangea.cloud/docs/api/vault/v1-general#/v1/state/change-post).
|
1914
1912
|
|
1915
1913
|
Raises:
|
1916
1914
|
PangeaAPIException: If an API Error happens
|
@@ -2011,7 +2009,7 @@ class Vault(ServiceBase):
|
|
2011
2009
|
Returns:
|
2012
2010
|
A `PangeaResponse` where the encrypted object is returned in the
|
2013
2011
|
`response.result` field. Available response fields can be found in
|
2014
|
-
our [API documentation](https://pangea.cloud/docs/api/vault
|
2012
|
+
our [API documentation](https://pangea.cloud/docs/api/vault/v1-keys#/v1/key/encrypt/structured-post).
|
2015
2013
|
|
2016
2014
|
Raises:
|
2017
2015
|
PangeaAPIException: If an API error happens.
|
@@ -2067,7 +2065,7 @@ class Vault(ServiceBase):
|
|
2067
2065
|
Returns:
|
2068
2066
|
A `PangeaResponse` where the decrypted object is returned in the
|
2069
2067
|
`response.result` field. Available response fields can be found in
|
2070
|
-
our [API documentation](https://pangea.cloud/docs/api/vault
|
2068
|
+
our [API documentation](https://pangea.cloud/docs/api/vault/v1-keys#/v1/key/decrypt/structured-post).
|
2071
2069
|
|
2072
2070
|
Examples:
|
2073
2071
|
data = {"field1": [1, 2, "kxcbC9E9IlgVaSCChPWUMgUC3ko=", "6FfI/LCzatLRLNAc8SuBK/TDnGxp"], "field2": "data2"}
|
@@ -2211,7 +2209,7 @@ class Vault(ServiceBase):
|
|
2211
2209
|
Returns:
|
2212
2210
|
A `PangeaResponse` where the exported key is returned in the
|
2213
2211
|
`response.result` field. Available response fields can be found in
|
2214
|
-
our [API documentation](https://pangea.cloud/docs/api/vault
|
2212
|
+
our [API documentation](https://pangea.cloud/docs/api/vault/v1-general#/v1/export-post).
|
2215
2213
|
|
2216
2214
|
Raises:
|
2217
2215
|
PangeaAPIException: If an API error happens.
|
pangea/tools.py
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# Copyright 2022 Pangea Cyber Corporation
|
2
2
|
# Author: Pangea Cyber Corporation
|
3
|
+
from __future__ import annotations
|
3
4
|
|
4
5
|
import enum
|
5
6
|
import io
|
@@ -7,9 +8,10 @@ import json
|
|
7
8
|
import logging
|
8
9
|
import os
|
9
10
|
import sys
|
11
|
+
from collections.abc import Iterator
|
10
12
|
from datetime import datetime, timezone
|
11
13
|
from logging.handlers import TimedRotatingFileHandler
|
12
|
-
from typing import
|
14
|
+
from typing import Optional
|
13
15
|
|
14
16
|
from pangea.config import PangeaConfig
|
15
17
|
from pangea.exceptions import PangeaException
|
@@ -17,6 +19,8 @@ from pangea.services import Audit
|
|
17
19
|
|
18
20
|
|
19
21
|
class TestEnvironment(str, enum.Enum):
|
22
|
+
__test__ = False
|
23
|
+
|
20
24
|
DEVELOP = "DEV"
|
21
25
|
LIVE = "LVE"
|
22
26
|
STAGING = "STG"
|
@@ -28,15 +32,15 @@ class TestEnvironment(str, enum.Enum):
|
|
28
32
|
return str(self.value)
|
29
33
|
|
30
34
|
|
31
|
-
class Root(
|
35
|
+
class Root(dict):
|
32
36
|
size: int
|
33
37
|
tree_name: str
|
34
38
|
|
35
39
|
|
36
|
-
class Event(
|
40
|
+
class Event(dict):
|
37
41
|
membership_proof: str
|
38
42
|
leaf_index: Optional[int]
|
39
|
-
event:
|
43
|
+
event: dict
|
40
44
|
hash: str
|
41
45
|
tree_size: Optional[int]
|
42
46
|
|
@@ -68,7 +72,7 @@ def exit_with_error(message: str):
|
|
68
72
|
sys.exit(1)
|
69
73
|
|
70
74
|
|
71
|
-
def file_events(root_hashes:
|
75
|
+
def file_events(root_hashes: dict[int, str], f: io.TextIOWrapper) -> Iterator[Event]:
|
72
76
|
"""
|
73
77
|
Reads a file containing Events in JSON format with the following fields:
|
74
78
|
- membership_proof: str
|
@@ -111,8 +115,8 @@ def make_aware_datetime(d: datetime) -> datetime:
|
|
111
115
|
return d
|
112
116
|
|
113
117
|
|
114
|
-
def filter_deep_none(data:
|
115
|
-
return {k: v if not isinstance(v,
|
118
|
+
def filter_deep_none(data: dict) -> dict:
|
119
|
+
return {k: v if not isinstance(v, dict) else filter_deep_none(v) for k, v in data.items() if v is not None}
|
116
120
|
|
117
121
|
|
118
122
|
def _load_env_var(env_var_name: str) -> str:
|
@@ -183,7 +187,7 @@ class SequenceFollower:
|
|
183
187
|
self.numbers.remove(min_val)
|
184
188
|
min_val += 1
|
185
189
|
|
186
|
-
def holes(self) ->
|
190
|
+
def holes(self) -> list[int]:
|
187
191
|
if not self.numbers:
|
188
192
|
return []
|
189
193
|
|
@@ -192,7 +196,7 @@ class SequenceFollower:
|
|
192
196
|
return [val for val in range(min_val, max_val) if val not in self.numbers]
|
193
197
|
|
194
198
|
|
195
|
-
loggers:
|
199
|
+
loggers: dict[str, bool] = {}
|
196
200
|
|
197
201
|
|
198
202
|
def logger_set_pangea_config(logger_name: str, level=logging.DEBUG):
|
pangea/utils.py
CHANGED
@@ -60,7 +60,7 @@ def canonicalize(data: dict) -> str:
|
|
60
60
|
return json.dumps(
|
61
61
|
data, ensure_ascii=False, allow_nan=False, separators=(",", ":"), sort_keys=True, default=default_encoder
|
62
62
|
)
|
63
|
-
elif isinstance(data, datetime.datetime
|
63
|
+
elif isinstance(data, (datetime.datetime, datetime.date)):
|
64
64
|
return format_datetime(data)
|
65
65
|
else:
|
66
66
|
return str(data)
|
@@ -151,10 +151,8 @@ def get_crc32c(data: str) -> str:
|
|
151
151
|
|
152
152
|
|
153
153
|
def hash_256_filepath(filepath: str) -> str:
|
154
|
-
|
155
|
-
|
156
|
-
data.close()
|
157
|
-
return hash
|
154
|
+
with open(filepath, "rb") as data:
|
155
|
+
return sha256(data.read()).hexdigest()
|
158
156
|
|
159
157
|
|
160
158
|
def get_prefix(hash: str, len: int = 5):
|