pangea-sdk 6.1.1__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 +199 -35
  5. pangea/asyncio/services/__init__.py +3 -0
  6. pangea/asyncio/services/ai_guard.py +91 -2
  7. pangea/asyncio/services/audit.py +307 -2
  8. pangea/asyncio/services/authn.py +12 -2
  9. pangea/asyncio/services/base.py +4 -0
  10. pangea/asyncio/services/file_scan.py +7 -1
  11. pangea/asyncio/services/intel.py +6 -2
  12. pangea/asyncio/services/management.py +576 -0
  13. pangea/asyncio/services/prompt_guard.py +112 -2
  14. pangea/asyncio/services/redact.py +269 -4
  15. pangea/asyncio/services/sanitize.py +5 -1
  16. pangea/asyncio/services/share.py +5 -1
  17. pangea/asyncio/services/vault.py +4 -0
  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 +205 -52
  25. pangea/response.py +15 -12
  26. pangea/services/__init__.py +3 -0
  27. pangea/services/ai_guard.py +497 -16
  28. pangea/services/audit/audit.py +310 -8
  29. pangea/services/audit/models.py +279 -0
  30. pangea/services/audit/signing.py +1 -1
  31. pangea/services/audit/util.py +10 -10
  32. pangea/services/authn/authn.py +12 -2
  33. pangea/services/authn/models.py +3 -0
  34. pangea/services/authz.py +4 -0
  35. pangea/services/base.py +5 -1
  36. pangea/services/embargo.py +6 -0
  37. pangea/services/file_scan.py +7 -1
  38. pangea/services/intel.py +4 -0
  39. pangea/services/management.py +720 -0
  40. pangea/services/prompt_guard.py +193 -2
  41. pangea/services/redact.py +477 -7
  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 +2 -4
  48. pangea/tools.py +13 -9
  49. pangea/utils.py +3 -5
  50. pangea/verify_audit.py +23 -27
  51. {pangea_sdk-6.1.1.dist-info → pangea_sdk-6.2.0b2.dist-info}/METADATA +4 -4
  52. pangea_sdk-6.2.0b2.dist-info/RECORD +62 -0
  53. pangea_sdk-6.1.1.dist-info/RECORD +0 -60
  54. {pangea_sdk-6.1.1.dist-info → pangea_sdk-6.2.0b2.dist-info}/WHEEL +0 -0
pangea/services/redact.py CHANGED
@@ -1,14 +1,80 @@
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
- from typing import Dict, List, Optional, Union
10
+ from collections.abc import Mapping, Sequence
11
+ from typing import Dict, List, Optional, Union, cast, overload
12
+
13
+ from pydantic import Field, TypeAdapter
14
+ from typing_extensions import Annotated, Literal
7
15
 
8
16
  from pangea.config import PangeaConfig
9
17
  from pangea.response import APIRequestModel, APIResponseModel, PangeaResponse, PangeaResponseResult
10
18
  from pangea.services.base import ServiceBase
11
19
 
20
+ MatcherType = Literal[
21
+ "CREDIT_CARD",
22
+ "CRYPTO",
23
+ "DATE_TIME",
24
+ "EMAIL_ADDRESS",
25
+ "IBAN_CODE",
26
+ "IP_ADDRESS",
27
+ "NRP",
28
+ "LOCATION",
29
+ "PERSON",
30
+ "PHONE_NUMBER",
31
+ "MEDICAL_LICENSE",
32
+ "URL",
33
+ "US_BANK_NUMBER",
34
+ "US_DRIVER_LICENSE",
35
+ "US_ITIN",
36
+ "US_PASSPORT",
37
+ "US_SSN",
38
+ "UK_NHS",
39
+ "NIF",
40
+ "FIN/NRIC",
41
+ "AU_ABN",
42
+ "AU_ACN",
43
+ "AU_TFN",
44
+ "AU_MEDICARE",
45
+ "FIREBASE_URL",
46
+ "RSA_PRIVATE_KEY",
47
+ "SSH_DSA_PRIVATE_KEY",
48
+ "SSH_EC_PRIVATE_KEY",
49
+ "PGP_PRIVATE_KEY_BLOCK",
50
+ "AMAZON_AWS_ACCESS_KEY_ID",
51
+ "AMAZON_AWS_SECRET_ACCESS_KEY",
52
+ "AMAZON_MWS_AUTH_TOKEN",
53
+ "FACEBOOK_ACCESS_TOKEN",
54
+ "GITHUB_ACCESS_TOKEN",
55
+ "JWT_TOKEN",
56
+ "GOOGLE_API_KEY",
57
+ "GOOGLE_CLOUD_PLATFORM_API_KEY",
58
+ "GOOGLE_DRIVE_API_KEY",
59
+ "GOOGLE_CLOUD_PLATFORM_SERVICE_ACCOUNT",
60
+ "GOOGLE_GMAIL_API_KEY",
61
+ "YOUTUBE_API_KEY",
62
+ "MAILCHIMP_API_KEY",
63
+ "MAILGUN_API_KEY",
64
+ "MONEY",
65
+ "BASIC_AUTH",
66
+ "PICATIC_API_KEY",
67
+ "SLACK_TOKEN",
68
+ "SLACK_WEBHOOK",
69
+ "STRIPE_API_KEY",
70
+ "STRIPE_RESTRICTED_API_KEY",
71
+ "SQUARE_ACCESS_TOKEN",
72
+ "SQUARE_OAUTH_SECRET",
73
+ "TWILIO_API_KEY",
74
+ "PANGEA_TOKEN",
75
+ "PROFANITY",
76
+ ]
77
+
12
78
 
13
79
  class RedactFormat(str, enum.Enum):
14
80
  """Structured data format."""
@@ -44,10 +110,10 @@ class PartialMasking(APIRequestModel):
44
110
  masked_from_left: Optional[int] = None
45
111
  masked_from_right: Optional[int] = None
46
112
  chars_to_ignore: Optional[List[str]] = None
47
- masking_char: Optional[List[str]] = None
113
+ masking_char: Optional[str] = Field(min_length=1, max_length=1)
48
114
 
49
115
 
50
- class RedactionMethodOverrides(APIRequestModel):
116
+ class Redaction(APIRequestModel):
51
117
  redaction_type: RedactType
52
118
  hash: Optional[Dict] = None
53
119
  fpe_alphabet: Optional[FPEAlphabet] = None
@@ -55,6 +121,10 @@ class RedactionMethodOverrides(APIRequestModel):
55
121
  redaction_value: Optional[str] = None
56
122
 
57
123
 
124
+ class RedactionMethodOverrides(Redaction):
125
+ """This field allows users to specify the redaction method per rule and its various parameters."""
126
+
127
+
58
128
  class RedactRequest(APIRequestModel):
59
129
  """
60
130
  Input class to make a redact request
@@ -65,7 +135,7 @@ class RedactRequest(APIRequestModel):
65
135
  rules: Optional[List[str]] = None
66
136
  rulesets: Optional[List[str]] = None
67
137
  return_result: Optional[bool] = None
68
- redaction_method_overrides: Optional[RedactionMethodOverrides] = None
138
+ redaction_method_overrides: Optional[Mapping[str, RedactionMethodOverrides]] = None
69
139
  vault_parameters: Optional[VaultParameters] = None
70
140
  llm_request: Optional[bool] = None
71
141
  """Is this redact call going to be used in an LLM request?"""
@@ -146,7 +216,7 @@ class StructuredRequest(APIRequestModel):
146
216
  rules: Optional[List[str]] = None
147
217
  rulesets: Optional[List[str]] = None
148
218
  return_result: Optional[bool] = None
149
- redaction_method_overrides: Optional[RedactionMethodOverrides] = None
219
+ redaction_method_overrides: Optional[Mapping[str, RedactionMethodOverrides]] = None
150
220
  vault_parameters: Optional[VaultParameters] = None
151
221
  llm_request: Optional[bool] = None
152
222
  """Is this redact call going to be used in an LLM request?"""
@@ -194,6 +264,145 @@ class UnredactResult(PangeaResponseResult):
194
264
  data: RedactedData
195
265
 
196
266
 
267
+ class Matcher(APIResponseModel):
268
+ match_type: str
269
+ match_value: str
270
+ match_score: float
271
+
272
+
273
+ class RuleV1(APIResponseModel):
274
+ entity_name: str
275
+ matchers: Union[List[Matcher], MatcherType]
276
+ ruleset: str
277
+
278
+ match_threshold: Optional[float] = None
279
+ context_values: Optional[List[str]] = None
280
+ name: Optional[str] = None
281
+ description: Optional[str] = None
282
+
283
+
284
+ class RuleV2(APIResponseModel):
285
+ entity_name: str
286
+ matchers: Union[List[Matcher], MatcherType]
287
+
288
+ match_threshold: Optional[float] = None
289
+ context_values: Optional[List[str]] = None
290
+ negative_context_values: Optional[List[str]] = None
291
+ name: Optional[str] = None
292
+ description: Optional[str] = None
293
+
294
+
295
+ class RulesetV1(APIResponseModel):
296
+ name: Optional[str] = None
297
+ description: Optional[str] = None
298
+ rules: List[str]
299
+
300
+
301
+ class RulesetV2(APIResponseModel):
302
+ name: Optional[str] = None
303
+ description: Optional[str] = None
304
+
305
+
306
+ class ServiceConfigV1(PangeaResponseResult):
307
+ version: Literal["1.0.0"] = "1.0.0"
308
+ id: str
309
+ name: str
310
+ updated_at: str
311
+ enabled_rules: List[str]
312
+
313
+ redactions: Optional[Dict[str, Redaction]] = None
314
+
315
+ vault_service_config_id: Optional[str] = None
316
+ """Service config used to create the secret"""
317
+
318
+ salt_vault_secret_id: Optional[str] = None
319
+ """Pangea only allows hashing to be done using a salt value to prevent brute-force attacks."""
320
+
321
+ rules: Optional[Dict[str, RuleV1]] = None
322
+ rulesets: Optional[Dict[str, RulesetV1]] = None
323
+ supported_languages: Optional[List[Literal["en"]]] = None
324
+
325
+
326
+ class ServiceConfigV2(PangeaResponseResult):
327
+ version: Literal["2.0.0"] = "2.0.0"
328
+ id: str
329
+ name: str
330
+ updated_at: str
331
+ enabled_rules: List[str]
332
+
333
+ enforce_enabled_rules: Optional[bool] = None
334
+ """Always run service config enabled rules across all redact calls regardless of flags?"""
335
+
336
+ redactions: Optional[Dict[str, Redaction]] = None
337
+
338
+ vault_service_config_id: Optional[str] = None
339
+ """Service config used to create the secret"""
340
+
341
+ salt_vault_secret_id: Optional[str] = None
342
+ """Pangea only allows hashing to be done using a salt value to prevent brute-force attacks."""
343
+
344
+ fpe_vault_secret_id: Optional[str] = None
345
+ """The ID of the key used by FF3 Encryption algorithms for FPE."""
346
+
347
+ rules: Optional[Dict[str, RuleV2]] = None
348
+ rulesets: Optional[Dict[str, RulesetV2]] = None
349
+ supported_languages: Optional[List[Literal["en"]]] = None
350
+
351
+
352
+ ServiceConfigResult = Annotated[Union[ServiceConfigV1, ServiceConfigV2], Field(discriminator="version")]
353
+
354
+
355
+ class ServiceConfigFilter(APIRequestModel):
356
+ id: Optional[str] = None
357
+ """Only records where id equals this value."""
358
+
359
+ id__contains: Optional[Sequence[str]] = None
360
+ """Only records where id includes each substring."""
361
+
362
+ id__in: Optional[Sequence[str]] = None
363
+ """Only records where id equals one of the provided substrings."""
364
+
365
+ created_at: Optional[str] = None
366
+ """Only records where created_at equals this value."""
367
+
368
+ created_at__gt: Optional[str] = None
369
+ """Only records where created_at is greater than this value."""
370
+
371
+ created_at__gte: Optional[str] = None
372
+ """Only records where created_at is greater than or equal to this value."""
373
+
374
+ created_at__lt: Optional[str] = None
375
+ """Only records where created_at is less than this value."""
376
+
377
+ created_at__lte: Optional[str] = None
378
+ """Only records where created_at is less than or equal to this value."""
379
+
380
+ updated_at: Optional[str] = None
381
+ """Only records where updated_at equals this value."""
382
+
383
+ updated_at__gt: Optional[str] = None
384
+ """Only records where updated_at is greater than this value."""
385
+
386
+ updated_at__gte: Optional[str] = None
387
+ """Only records where updated_at is greater than or equal to this value."""
388
+
389
+ updated_at__lt: Optional[str] = None
390
+ """Only records where updated_at is less than this value."""
391
+
392
+ updated_at__lte: Optional[str] = None
393
+ """Only records where updated_at is less than or equal to this value."""
394
+
395
+
396
+ class ServiceConfigListResult(PangeaResponseResult):
397
+ count: int
398
+ """The total number of service configs matched by the list request."""
399
+
400
+ last: str
401
+ """Used to fetch the next page of the current listing when provided in a repeated request's last parameter."""
402
+
403
+ items: Sequence[ServiceConfigResult]
404
+
405
+
197
406
  class Redact(ServiceBase):
198
407
  """Redact service client.
199
408
 
@@ -248,7 +457,7 @@ class Redact(ServiceBase):
248
457
  rules: Optional[List[str]] = None,
249
458
  rulesets: Optional[List[str]] = None,
250
459
  return_result: Optional[bool] = None,
251
- redaction_method_overrides: Optional[RedactionMethodOverrides] = None,
460
+ redaction_method_overrides: Optional[Mapping[str, RedactionMethodOverrides]] = None,
252
461
  llm_request: Optional[bool] = None,
253
462
  vault_parameters: Optional[VaultParameters] = None,
254
463
  ) -> PangeaResponse[RedactResult]:
@@ -303,7 +512,7 @@ class Redact(ServiceBase):
303
512
  rules: Optional[List[str]] = None,
304
513
  rulesets: Optional[List[str]] = None,
305
514
  return_result: Optional[bool] = None,
306
- redaction_method_overrides: Optional[RedactionMethodOverrides] = None,
515
+ redaction_method_overrides: Mapping[str, RedactionMethodOverrides] | None = None,
307
516
  llm_request: Optional[bool] = None,
308
517
  vault_parameters: Optional[VaultParameters] = None,
309
518
  ) -> PangeaResponse[StructuredResult]:
@@ -382,3 +591,264 @@ class Redact(ServiceBase):
382
591
  """
383
592
  input = UnredactRequest(redacted_data=redacted_data, fpe_context=fpe_context)
384
593
  return self.request.post("v1/unredact", UnredactResult, data=input.model_dump(exclude_none=True))
594
+
595
+ def get_service_config(self, config_id: str) -> PangeaResponse[ServiceConfigResult]:
596
+ """
597
+ Get a service config.
598
+
599
+
600
+ OperationId: redact_post_v1beta_config
601
+ """
602
+ response = self.request.post("v1beta/config", PangeaResponseResult, data={"id": config_id})
603
+ response.result = TypeAdapter(ServiceConfigResult).validate_python(response.json["result"])
604
+ return cast(PangeaResponse[ServiceConfigResult], response)
605
+
606
+ @overload
607
+ def create_service_config(
608
+ self,
609
+ name: str,
610
+ *,
611
+ version: Literal["1.0.0"],
612
+ enabled_rules: Sequence[str] | None = None,
613
+ redactions: Mapping[str, Redaction] | None = None,
614
+ vault_service_config_id: str | None = None,
615
+ salt_vault_secret_id: str | None = None,
616
+ rules: Mapping[str, RuleV1] | None = None,
617
+ rulesets: Mapping[str, RulesetV1] | None = None,
618
+ supported_languages: Sequence[Literal["en"]] | None = None,
619
+ ) -> PangeaResponse[ServiceConfigResult]:
620
+ """
621
+ Create a v1.0.0 service config.
622
+
623
+ OperationId: redact_post_v1beta_config_create
624
+
625
+ Args:
626
+ vault_service_config_id: Service config used to create the secret
627
+ salt_vault_secret_id: Pangea only allows hashing to be done using a salt value to prevent brute-force attacks.
628
+ """
629
+
630
+ @overload
631
+ def create_service_config(
632
+ self,
633
+ name: str,
634
+ *,
635
+ version: Literal["2.0.0"] | None = None,
636
+ enabled_rules: Sequence[str] | None = None,
637
+ enforce_enabled_rules: bool | None = None,
638
+ redactions: Mapping[str, Redaction] | None = None,
639
+ vault_service_config_id: str | None = None,
640
+ salt_vault_secret_id: str | None = None,
641
+ fpe_vault_secret_id: str | None = None,
642
+ rules: Mapping[str, RuleV2] | None = None,
643
+ rulesets: Mapping[str, RulesetV2] | None = None,
644
+ supported_languages: Sequence[Literal["en"]] | None = None,
645
+ ) -> PangeaResponse[ServiceConfigResult]:
646
+ """
647
+ Create a v2.0.0 service config.
648
+
649
+ OperationId: redact_post_v1beta_config_create
650
+
651
+ Args:
652
+ enforce_enabled_rules: Always run service config enabled rules across all redact calls regardless of flags?
653
+ vault_service_config_id: Service config used to create the secret
654
+ salt_vault_secret_id: Pangea only allows hashing to be done using a salt value to prevent brute-force attacks.
655
+ fpe_vault_secret_id: The ID of the key used by FF3 Encryption algorithms for FPE.
656
+ """
657
+
658
+ def create_service_config(
659
+ self,
660
+ name: str,
661
+ *,
662
+ version: Literal["1.0.0", "2.0.0"] | None = None,
663
+ enabled_rules: Sequence[str] | None = None,
664
+ enforce_enabled_rules: bool | None = None,
665
+ fpe_vault_secret_id: str | None = None,
666
+ redactions: Mapping[str, Redaction] | None = None,
667
+ rules: Mapping[str, RuleV1 | RuleV2] | None = None,
668
+ rulesets: Mapping[str, RulesetV1 | RulesetV2] | None = None,
669
+ salt_vault_secret_id: str | None = None,
670
+ supported_languages: Sequence[Literal["en"]] | None = None,
671
+ vault_service_config_id: str | None = None,
672
+ ) -> PangeaResponse[ServiceConfigResult]:
673
+ """
674
+ Create a service config.
675
+
676
+ OperationId: redact_post_v1beta_config_create
677
+
678
+ Args:
679
+ enforce_enabled_rules: Always run service config enabled rules across all redact calls regardless of flags?
680
+ fpe_vault_secret_id: The ID of the key used by FF3 Encryption algorithms for FPE.
681
+ salt_vault_secret_id: Pangea only allows hashing to be done using a salt value to prevent brute-force attacks.
682
+ vault_service_config_id: Service config used to create the secret
683
+ """
684
+
685
+ response = self.request.post(
686
+ "v1beta/config/create",
687
+ PangeaResponseResult,
688
+ data={
689
+ "name": name,
690
+ "version": version,
691
+ "enabled_rules": enabled_rules,
692
+ "enforce_enabled_rules": enforce_enabled_rules,
693
+ "fpe_vault_secret_id": fpe_vault_secret_id,
694
+ "redactions": redactions,
695
+ "rules": rules,
696
+ "rulesets": rulesets,
697
+ "salt_vault_secret_id": salt_vault_secret_id,
698
+ "supported_languages": supported_languages,
699
+ "vault_service_config_id": vault_service_config_id,
700
+ },
701
+ )
702
+ response.result = TypeAdapter(ServiceConfigResult).validate_python(response.json["result"])
703
+ return cast(PangeaResponse[ServiceConfigResult], response)
704
+
705
+ @overload
706
+ def update_service_config(
707
+ self,
708
+ config_id: str,
709
+ *,
710
+ version: Literal["1.0.0"],
711
+ name: str,
712
+ updated_at: str,
713
+ enabled_rules: Sequence[str] | None = None,
714
+ redactions: Mapping[str, Redaction] | None = None,
715
+ vault_service_config_id: str | None = None,
716
+ salt_vault_secret_id: str | None = None,
717
+ rules: Mapping[str, RuleV1] | None = None,
718
+ rulesets: Mapping[str, RulesetV1] | None = None,
719
+ supported_languages: Sequence[Literal["en"]] | None = None,
720
+ ) -> PangeaResponse[ServiceConfigResult]:
721
+ """
722
+ Update a v1.0.0 service config.
723
+
724
+ OperationId: redact_post_v1beta_config_update
725
+
726
+ Args:
727
+ vault_service_config_id: Service config used to create the secret
728
+ salt_vault_secret_id: Pangea only allows hashing to be done using a salt value to prevent brute-force attacks.
729
+ """
730
+
731
+ @overload
732
+ def update_service_config(
733
+ self,
734
+ config_id: str,
735
+ *,
736
+ version: Literal["2.0.0"] | None = None,
737
+ name: str,
738
+ updated_at: str,
739
+ enabled_rules: Sequence[str] | None = None,
740
+ enforce_enabled_rules: bool | None = None,
741
+ redactions: Mapping[str, Redaction] | None = None,
742
+ vault_service_config_id: str | None = None,
743
+ salt_vault_secret_id: str | None = None,
744
+ fpe_vault_secret_id: str | None = None,
745
+ rules: Mapping[str, RuleV2] | None = None,
746
+ rulesets: Mapping[str, RulesetV2] | None = None,
747
+ supported_languages: Sequence[Literal["en"]] | None = None,
748
+ ) -> PangeaResponse[ServiceConfigResult]:
749
+ """
750
+ Update a v2.0.0 service config.
751
+
752
+ OperationId: redact_post_v1beta_config_update
753
+
754
+ Args:
755
+ enforce_enabled_rules: Always run service config enabled rules across all redact calls regardless of flags?
756
+ vault_service_config_id: Service config used to create the secret
757
+ salt_vault_secret_id: Pangea only allows hashing to be done using a salt value to prevent brute-force attacks.
758
+ fpe_vault_secret_id: The ID of the key used by FF3 Encryption algorithms for FPE.
759
+ """
760
+
761
+ def update_service_config(
762
+ self,
763
+ config_id: str,
764
+ *,
765
+ version: Literal["1.0.0", "2.0.0"] | None = None,
766
+ name: str,
767
+ updated_at: str,
768
+ enabled_rules: Sequence[str] | None = None,
769
+ enforce_enabled_rules: bool | None = None,
770
+ fpe_vault_secret_id: str | None = None,
771
+ redactions: Mapping[str, Redaction] | None = None,
772
+ rules: Mapping[str, RuleV1 | RuleV2] | None = None,
773
+ rulesets: Mapping[str, RulesetV1 | RulesetV2] | None = None,
774
+ salt_vault_secret_id: str | None = None,
775
+ supported_languages: Sequence[Literal["en"]] | None = None,
776
+ vault_service_config_id: str | None = None,
777
+ ) -> PangeaResponse[ServiceConfigResult]:
778
+ """
779
+ Update a service config.
780
+
781
+ OperationId: redact_post_v1beta_config_update
782
+
783
+ Args:
784
+ enforce_enabled_rules: Always run service config enabled rules across all redact calls regardless of flags?
785
+ fpe_vault_secret_id: The ID of the key used by FF3 Encryption algorithms for FPE.
786
+ salt_vault_secret_id: Pangea only allows hashing to be done using a salt value to prevent brute-force attacks.
787
+ vault_service_config_id: Service config used to create the secret
788
+ """
789
+
790
+ response = self.request.post(
791
+ "v1beta/config/update",
792
+ PangeaResponseResult,
793
+ data={
794
+ "id": config_id,
795
+ "updated_at": updated_at,
796
+ "name": name,
797
+ "version": version,
798
+ "enabled_rules": enabled_rules,
799
+ "enforce_enabled_rules": enforce_enabled_rules,
800
+ "fpe_vault_secret_id": fpe_vault_secret_id,
801
+ "redactions": redactions,
802
+ "rules": rules,
803
+ "rulesets": rulesets,
804
+ "salt_vault_secret_id": salt_vault_secret_id,
805
+ "supported_languages": supported_languages,
806
+ "vault_service_config_id": vault_service_config_id,
807
+ },
808
+ )
809
+ response.result = TypeAdapter(ServiceConfigResult).validate_python(response.json["result"])
810
+ return cast(PangeaResponse[ServiceConfigResult], response)
811
+
812
+ def delete_service_config(
813
+ self,
814
+ config_id: str,
815
+ ) -> PangeaResponse[ServiceConfigResult]:
816
+ """
817
+ Delete a service config.
818
+
819
+ OperationId: redact_post_v1beta_config_delete
820
+
821
+ Args:
822
+ config_id: An ID for a service config
823
+ """
824
+
825
+ response = self.request.post("v1beta/config/delete", PangeaResponseResult, data={"id": config_id})
826
+ response.result = TypeAdapter(ServiceConfigResult).validate_python(response.json["result"])
827
+ return cast(PangeaResponse[ServiceConfigResult], response)
828
+
829
+ def list_service_configs(
830
+ self,
831
+ *,
832
+ filter: ServiceConfigFilter | None = None,
833
+ last: str | None = None,
834
+ order: Literal["asc", "desc"] | None = None,
835
+ order_by: Literal["id", "created_at", "updated_at"] | None = None,
836
+ size: int | None = None,
837
+ ) -> PangeaResponse[ServiceConfigListResult]:
838
+ """
839
+ List service configs.
840
+
841
+ OperationId: redact_post_v1beta_config_list
842
+
843
+ Args:
844
+ last: Reflected value from a previous response to obtain the next page of results.
845
+ order: Order results asc(ending) or desc(ending).
846
+ order_by: Which field to order results by.
847
+ size: Maximum results to include in the response.
848
+ """
849
+
850
+ return self.request.post(
851
+ "v1beta/config/list",
852
+ ServiceConfigListResult,
853
+ data={"filter": filter, "last": last, "order": order, "order_by": order_by, "size": size},
854
+ )
@@ -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):