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.
Files changed (54) hide show
  1. pangea/__init__.py +9 -1
  2. pangea/asyncio/__init__.py +1 -0
  3. pangea/asyncio/file_uploader.py +4 -2
  4. pangea/asyncio/request.py +51 -21
  5. pangea/asyncio/services/__init__.py +2 -0
  6. pangea/asyncio/services/ai_guard.py +91 -2
  7. pangea/asyncio/services/audit.py +14 -8
  8. pangea/asyncio/services/authn.py +33 -23
  9. pangea/asyncio/services/authz.py +6 -6
  10. pangea/asyncio/services/base.py +4 -0
  11. pangea/asyncio/services/file_scan.py +8 -2
  12. pangea/asyncio/services/intel.py +6 -2
  13. pangea/asyncio/services/prompt_guard.py +112 -2
  14. pangea/asyncio/services/redact.py +7 -3
  15. pangea/asyncio/services/sanitize.py +5 -1
  16. pangea/asyncio/services/share.py +5 -1
  17. pangea/asyncio/services/vault.py +19 -15
  18. pangea/audit_logger.py +3 -1
  19. pangea/deep_verify.py +13 -13
  20. pangea/deprecated.py +1 -1
  21. pangea/dump_audit.py +2 -3
  22. pangea/exceptions.py +8 -5
  23. pangea/file_uploader.py +4 -0
  24. pangea/request.py +58 -41
  25. pangea/response.py +15 -12
  26. pangea/services/__init__.py +2 -0
  27. pangea/services/ai_guard.py +497 -16
  28. pangea/services/audit/audit.py +15 -13
  29. pangea/services/audit/models.py +4 -0
  30. pangea/services/audit/signing.py +1 -1
  31. pangea/services/audit/util.py +10 -10
  32. pangea/services/authn/authn.py +33 -23
  33. pangea/services/authn/models.py +3 -0
  34. pangea/services/authz.py +10 -6
  35. pangea/services/base.py +5 -1
  36. pangea/services/embargo.py +6 -0
  37. pangea/services/file_scan.py +8 -2
  38. pangea/services/intel.py +4 -0
  39. pangea/services/management.py +8 -8
  40. pangea/services/prompt_guard.py +193 -2
  41. pangea/services/redact.py +7 -3
  42. pangea/services/sanitize.py +5 -1
  43. pangea/services/share/share.py +13 -7
  44. pangea/services/vault/models/asymmetric.py +4 -0
  45. pangea/services/vault/models/common.py +4 -0
  46. pangea/services/vault/models/symmetric.py +4 -0
  47. pangea/services/vault/vault.py +17 -19
  48. pangea/tools.py +13 -9
  49. pangea/utils.py +3 -5
  50. pangea/verify_audit.py +23 -27
  51. {pangea_sdk-6.2.0b1.dist-info → pangea_sdk-6.2.0b2.dist-info}/METADATA +6 -6
  52. pangea_sdk-6.2.0b2.dist-info/RECORD +62 -0
  53. {pangea_sdk-6.2.0b1.dist-info → pangea_sdk-6.2.0b2.dist-info}/WHEEL +1 -1
  54. pangea_sdk-6.2.0b1.dist-info/RECORD +0 -62
@@ -1,9 +1,12 @@
1
1
  from __future__ import annotations
2
2
 
3
- from typing import TYPE_CHECKING, Literal, Optional
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))
@@ -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
@@ -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, NewType, Optional, Tuple, Union
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 = NewType("Metadata", Dict[str, str])
16
- Tags = NewType("Tags", List[str])
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: List[str] = [],
920
- format: Optional[ArchiveFormat] = None,
921
- transfer_method: Optional[TransferMethod] = None,
922
- bucket_id: Optional[str] = None,
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
@@ -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
  from enum import Enum
@@ -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
@@ -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
  from enum import Enum
@@ -2,10 +2,9 @@
2
2
  # Author: Pangea Cyber Corporation
3
3
  from __future__ import annotations
4
4
 
5
- from typing import TYPE_CHECKING, Any, List, Literal, Optional, Union, cast, overload
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: List[VaultItem]
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#delete).
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#retrieve).
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#list).
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#update).
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#encrypt).
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#decrypt).
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#sign).
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#verify).
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#verify-jwt).
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#sign-a-jwt).
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#retrieve-jwk).
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#change-state).
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#encrypt-structured).
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#decrypt-structured).
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#export).
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 Dict, Iterator, List, Optional
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(Dict):
35
+ class Root(dict):
32
36
  size: int
33
37
  tree_name: str
34
38
 
35
39
 
36
- class Event(Dict):
40
+ class Event(dict):
37
41
  membership_proof: str
38
42
  leaf_index: Optional[int]
39
- event: Dict
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: Dict[int, str], f: io.TextIOWrapper) -> Iterator[Event]:
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: Dict) -> Dict:
115
- return {k: v if not isinstance(v, Dict) else filter_deep_none(v) for k, v in data.items() if v is not None}
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) -> List[int]:
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: Dict[str, bool] = {}
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) or isinstance(data, datetime.date):
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
- data = open(filepath, "rb")
155
- hash = sha256(data.read()).hexdigest()
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):