pangea-sdk 3.8.0b1__py3-none-any.whl → 5.4.0b1__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. pangea/__init__.py +1 -1
  2. pangea/asyncio/file_uploader.py +1 -1
  3. pangea/asyncio/request.py +56 -34
  4. pangea/asyncio/services/__init__.py +4 -0
  5. pangea/asyncio/services/ai_guard.py +75 -0
  6. pangea/asyncio/services/audit.py +192 -31
  7. pangea/asyncio/services/authn.py +187 -109
  8. pangea/asyncio/services/authz.py +285 -0
  9. pangea/asyncio/services/base.py +21 -2
  10. pangea/asyncio/services/embargo.py +2 -2
  11. pangea/asyncio/services/file_scan.py +24 -9
  12. pangea/asyncio/services/intel.py +108 -34
  13. pangea/asyncio/services/prompt_guard.py +73 -0
  14. pangea/asyncio/services/redact.py +72 -4
  15. pangea/asyncio/services/sanitize.py +217 -0
  16. pangea/asyncio/services/share.py +246 -73
  17. pangea/asyncio/services/vault.py +1710 -750
  18. pangea/crypto/rsa.py +135 -0
  19. pangea/deep_verify.py +7 -1
  20. pangea/dump_audit.py +9 -8
  21. pangea/request.py +87 -59
  22. pangea/response.py +49 -31
  23. pangea/services/__init__.py +4 -0
  24. pangea/services/ai_guard.py +128 -0
  25. pangea/services/audit/audit.py +205 -42
  26. pangea/services/audit/models.py +56 -8
  27. pangea/services/audit/signing.py +6 -5
  28. pangea/services/audit/util.py +3 -3
  29. pangea/services/authn/authn.py +140 -70
  30. pangea/services/authn/models.py +167 -11
  31. pangea/services/authz.py +400 -0
  32. pangea/services/base.py +39 -8
  33. pangea/services/embargo.py +2 -2
  34. pangea/services/file_scan.py +32 -15
  35. pangea/services/intel.py +157 -32
  36. pangea/services/prompt_guard.py +83 -0
  37. pangea/services/redact.py +152 -4
  38. pangea/services/sanitize.py +371 -0
  39. pangea/services/share/share.py +683 -107
  40. pangea/services/vault/models/asymmetric.py +120 -18
  41. pangea/services/vault/models/common.py +439 -141
  42. pangea/services/vault/models/keys.py +94 -0
  43. pangea/services/vault/models/secret.py +27 -3
  44. pangea/services/vault/models/symmetric.py +68 -22
  45. pangea/services/vault/vault.py +1690 -749
  46. pangea/tools.py +6 -7
  47. pangea/utils.py +16 -27
  48. pangea/verify_audit.py +270 -83
  49. {pangea_sdk-3.8.0b1.dist-info → pangea_sdk-5.4.0b1.dist-info}/METADATA +43 -35
  50. pangea_sdk-5.4.0b1.dist-info/RECORD +60 -0
  51. {pangea_sdk-3.8.0b1.dist-info → pangea_sdk-5.4.0b1.dist-info}/WHEEL +1 -1
  52. pangea_sdk-3.8.0b1.dist-info/RECORD +0 -50
@@ -67,7 +67,9 @@ class FileIntelAsync(ServiceBaseAsync):
67
67
 
68
68
  """
69
69
  input = m.FileReputationRequest(hash=hash, hash_type=hash_type, verbose=verbose, raw=raw, provider=provider)
70
- return await self.request.post("v1/reputation", m.FileReputationResult, data=input.dict(exclude_none=True))
70
+ return await self.request.post(
71
+ "v1/reputation", m.FileReputationResult, data=input.model_dump(exclude_none=True)
72
+ )
71
73
 
72
74
  async def hash_reputation_bulk(
73
75
  self,
@@ -76,7 +78,7 @@ class FileIntelAsync(ServiceBaseAsync):
76
78
  provider: Optional[str] = None,
77
79
  verbose: Optional[bool] = None,
78
80
  raw: Optional[bool] = None,
79
- ) -> PangeaResponse[m.FileReputationResult]:
81
+ ) -> PangeaResponse[m.FileReputationBulkResult]:
80
82
  """
81
83
  Reputation check
82
84
 
@@ -103,7 +105,9 @@ class FileIntelAsync(ServiceBaseAsync):
103
105
  input = m.FileReputationBulkRequest( # type: ignore[call-arg]
104
106
  hashes=hashes, hash_type=hash_type, verbose=verbose, raw=raw, provider=provider
105
107
  )
106
- return await self.request.post("v2/reputation", m.FileReputationBulkResult, data=input.dict(exclude_none=True))
108
+ return await self.request.post(
109
+ "v2/reputation", m.FileReputationBulkResult, data=input.model_dump(exclude_none=True)
110
+ )
107
111
 
108
112
  async def filepath_reputation(
109
113
  self,
@@ -144,7 +148,9 @@ class FileIntelAsync(ServiceBaseAsync):
144
148
  hash = hashlib.sha256(data.read()).hexdigest()
145
149
 
146
150
  input = m.FileReputationRequest(hash=hash, hash_type="sha256", verbose=verbose, raw=raw, provider=provider)
147
- return await self.request.post("v1/reputation", m.FileReputationResult, data=input.dict(exclude_none=True))
151
+ return await self.request.post(
152
+ "v1/reputation", m.FileReputationResult, data=input.model_dump(exclude_none=True)
153
+ )
148
154
 
149
155
  async def filepath_reputation_bulk(
150
156
  self,
@@ -182,7 +188,7 @@ class FileIntelAsync(ServiceBaseAsync):
182
188
  hash = hash_256_filepath(filepath)
183
189
  hashes.append(hash)
184
190
 
185
- return await self.hash_reputation_bulk( # type: ignore[return-value]
191
+ return await self.hash_reputation_bulk(
186
192
  hashes=hashes, hash_type="sha256", verbose=verbose, raw=raw, provider=provider
187
193
  )
188
194
 
@@ -243,7 +249,9 @@ class DomainIntelAsync(ServiceBaseAsync):
243
249
  )
244
250
  """
245
251
  input = m.DomainReputationRequest(domain=domain, verbose=verbose, provider=provider, raw=raw)
246
- return await self.request.post("v1/reputation", m.DomainReputationResult, data=input.dict(exclude_none=True))
252
+ return await self.request.post(
253
+ "v1/reputation", m.DomainReputationResult, data=input.model_dump(exclude_none=True)
254
+ )
247
255
 
248
256
  async def reputation_bulk(
249
257
  self,
@@ -251,7 +259,7 @@ class DomainIntelAsync(ServiceBaseAsync):
251
259
  verbose: Optional[bool] = None,
252
260
  raw: Optional[bool] = None,
253
261
  provider: Optional[str] = None,
254
- ) -> PangeaResponse[m.DomainReputationResult]:
262
+ ) -> PangeaResponse[m.DomainReputationBulkResult]:
255
263
  """
256
264
  Reputation
257
265
 
@@ -277,7 +285,7 @@ class DomainIntelAsync(ServiceBaseAsync):
277
285
  """
278
286
  input = m.DomainReputationBulkRequest(domains=domains, verbose=verbose, provider=provider, raw=raw)
279
287
  return await self.request.post(
280
- "v2/reputation", m.DomainReputationBulkResult, data=input.dict(exclude_none=True)
288
+ "v2/reputation", m.DomainReputationBulkResult, data=input.model_dump(exclude_none=True)
281
289
  )
282
290
 
283
291
  async def who_is(
@@ -310,7 +318,7 @@ class DomainIntelAsync(ServiceBaseAsync):
310
318
  )
311
319
  """
312
320
  input = m.DomainWhoIsRequest(domain=domain, verbose=verbose, provider=provider, raw=raw) # type: ignore[call-arg]
313
- return await self.request.post("v1/whois", m.DomainWhoIsResult, data=input.dict(exclude_none=True))
321
+ return await self.request.post("v1/whois", m.DomainWhoIsResult, data=input.model_dump(exclude_none=True))
314
322
 
315
323
 
316
324
  class IpIntelAsync(ServiceBaseAsync):
@@ -353,7 +361,7 @@ class IpIntelAsync(ServiceBaseAsync):
353
361
  ip (str): The IP to be looked up
354
362
  verbose (bool, optional): Echo the API parameters in the response
355
363
  raw (bool, optional): Include raw data from this provider
356
- provider (str, optional): Use reputation data from this provider: "crowdstrike"
364
+ provider (str, optional): Use reputation data from this provider
357
365
 
358
366
  Raises:
359
367
  PangeaAPIException: If an API Error happens
@@ -369,11 +377,11 @@ class IpIntelAsync(ServiceBaseAsync):
369
377
  )
370
378
  """
371
379
  input = m.IPReputationRequest(ip=ip, verbose=verbose, raw=raw, provider=provider)
372
- return await self.request.post("v1/reputation", m.IPReputationResult, data=input.dict(exclude_none=True))
380
+ return await self.request.post("v1/reputation", m.IPReputationResult, data=input.model_dump(exclude_none=True))
373
381
 
374
382
  async def reputation_bulk(
375
383
  self, ips: List[str], verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
376
- ) -> PangeaResponse[m.IPReputationResult]:
384
+ ) -> PangeaResponse[m.IPReputationBulkResult]:
377
385
  """
378
386
  Reputation
379
387
 
@@ -385,7 +393,7 @@ class IpIntelAsync(ServiceBaseAsync):
385
393
  ips (List[str]): The IP list to be looked up
386
394
  verbose (bool, optional): Echo the API parameters in the response
387
395
  raw (bool, optional): Include raw data from this provider
388
- provider (str, optional): Use reputation data from this provider: "crowdstrike"
396
+ provider (str, optional): Use reputation data from this provider
389
397
 
390
398
  Raises:
391
399
  PangeaAPIException: If an API Error happens
@@ -398,7 +406,9 @@ class IpIntelAsync(ServiceBaseAsync):
398
406
  FIXME:
399
407
  """
400
408
  input = m.IPReputationBulkRequest(ips=ips, verbose=verbose, raw=raw, provider=provider)
401
- return await self.request.post("v2/reputation", m.IPReputationBulkResult, data=input.dict(exclude_none=True))
409
+ return await self.request.post(
410
+ "v2/reputation", m.IPReputationBulkResult, data=input.model_dump(exclude_none=True)
411
+ )
402
412
 
403
413
  async def geolocate(
404
414
  self, ip: str, verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
@@ -430,7 +440,7 @@ class IpIntelAsync(ServiceBaseAsync):
430
440
  )
431
441
  """
432
442
  input = m.IPGeolocateRequest(ip=ip, verbose=verbose, raw=raw, provider=provider)
433
- return await self.request.post("v1/geolocate", m.IPGeolocateResult, data=input.dict(exclude_none=True))
443
+ return await self.request.post("v1/geolocate", m.IPGeolocateResult, data=input.model_dump(exclude_none=True))
434
444
 
435
445
  async def geolocate_bulk(
436
446
  self, ips: List[str], verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
@@ -459,7 +469,9 @@ class IpIntelAsync(ServiceBaseAsync):
459
469
  FIXME:
460
470
  """
461
471
  input = m.IPGeolocateBulkRequest(ips=ips, verbose=verbose, raw=raw, provider=provider)
462
- return await self.request.post("v2/geolocate", m.IPGeolocateBulkResult, data=input.dict(exclude_none=True))
472
+ return await self.request.post(
473
+ "v2/geolocate", m.IPGeolocateBulkResult, data=input.model_dump(exclude_none=True)
474
+ )
463
475
 
464
476
  async def get_domain(
465
477
  self, ip: str, verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
@@ -491,7 +503,7 @@ class IpIntelAsync(ServiceBaseAsync):
491
503
  )
492
504
  """
493
505
  input = m.IPDomainRequest(ip=ip, verbose=verbose, raw=raw, provider=provider)
494
- return await self.request.post("v1/domain", m.IPDomainResult, data=input.dict(exclude_none=True))
506
+ return await self.request.post("v1/domain", m.IPDomainResult, data=input.model_dump(exclude_none=True))
495
507
 
496
508
  async def get_domain_bulk(
497
509
  self, ips: List[str], verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
@@ -520,7 +532,7 @@ class IpIntelAsync(ServiceBaseAsync):
520
532
  FIXME:
521
533
  """
522
534
  input = m.IPDomainBulkRequest(ips=ips, verbose=verbose, raw=raw, provider=provider)
523
- return await self.request.post("v2/domain", m.IPDomainBulkResult, data=input.dict(exclude_none=True))
535
+ return await self.request.post("v2/domain", m.IPDomainBulkResult, data=input.model_dump(exclude_none=True))
524
536
 
525
537
  async def is_vpn(
526
538
  self, ip: str, verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
@@ -552,7 +564,7 @@ class IpIntelAsync(ServiceBaseAsync):
552
564
  )
553
565
  """
554
566
  input = m.IPVPNRequest(ip=ip, verbose=verbose, raw=raw, provider=provider)
555
- return await self.request.post("v1/vpn", m.IPVPNResult, data=input.dict(exclude_none=True))
567
+ return await self.request.post("v1/vpn", m.IPVPNResult, data=input.model_dump(exclude_none=True))
556
568
 
557
569
  async def is_vpn_bulk(
558
570
  self, ips: List[str], verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
@@ -581,7 +593,7 @@ class IpIntelAsync(ServiceBaseAsync):
581
593
  FIXME:
582
594
  """
583
595
  input = m.IPVPNBulkRequest(ips=ips, verbose=verbose, raw=raw, provider=provider)
584
- return await self.request.post("v2/vpn", m.IPVPNBulkResult, data=input.dict(exclude_none=True))
596
+ return await self.request.post("v2/vpn", m.IPVPNBulkResult, data=input.model_dump(exclude_none=True))
585
597
 
586
598
  async def is_proxy(
587
599
  self, ip: str, verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
@@ -613,7 +625,7 @@ class IpIntelAsync(ServiceBaseAsync):
613
625
  )
614
626
  """
615
627
  input = m.IPProxyRequest(ip=ip, verbose=verbose, raw=raw, provider=provider)
616
- return await self.request.post("v1/proxy", m.IPProxyResult, data=input.dict(exclude_none=True))
628
+ return await self.request.post("v1/proxy", m.IPProxyResult, data=input.model_dump(exclude_none=True))
617
629
 
618
630
  async def is_proxy_bulk(
619
631
  self, ips: List[str], verbose: Optional[bool] = None, raw: Optional[bool] = None, provider: Optional[str] = None
@@ -642,7 +654,7 @@ class IpIntelAsync(ServiceBaseAsync):
642
654
  FIXME:
643
655
  """
644
656
  input = m.IPProxyBulkRequest(ips=ips, verbose=verbose, raw=raw, provider=provider)
645
- return await self.request.post("v2/proxy", m.IPProxyBulkResult, data=input.dict(exclude_none=True))
657
+ return await self.request.post("v2/proxy", m.IPProxyBulkResult, data=input.model_dump(exclude_none=True))
646
658
 
647
659
 
648
660
  class UrlIntelAsync(ServiceBaseAsync):
@@ -685,7 +697,7 @@ class UrlIntelAsync(ServiceBaseAsync):
685
697
  url (str): The URL to be looked up
686
698
  verbose (bool, optional): Echo the API parameters in the response
687
699
  raw (bool, optional): Include raw data from this provider
688
- provider (str, optional): Use reputation data from this provider: "crowdstrike"
700
+ provider (str, optional): Use reputation data from this provider
689
701
 
690
702
  Raises:
691
703
  PangeaAPIException: If an API Error happens
@@ -702,7 +714,7 @@ class UrlIntelAsync(ServiceBaseAsync):
702
714
  """
703
715
 
704
716
  input = m.URLReputationRequest(url=url, provider=provider, verbose=verbose, raw=raw)
705
- return await self.request.post("v1/reputation", m.URLReputationResult, data=input.dict(exclude_none=True))
717
+ return await self.request.post("v1/reputation", m.URLReputationResult, data=input.model_dump(exclude_none=True))
706
718
 
707
719
  async def reputation_bulk(
708
720
  self,
@@ -722,7 +734,7 @@ class UrlIntelAsync(ServiceBaseAsync):
722
734
  urls (List[str]): The URL list to be looked up
723
735
  verbose (bool, optional): Echo the API parameters in the response
724
736
  raw (bool, optional): Include raw data from this provider
725
- provider (str, optional): Use reputation data from this provider: "crowdstrike"
737
+ provider (str, optional): Use reputation data from this provider
726
738
 
727
739
  Raises:
728
740
  PangeaAPIException: If an API Error happens
@@ -736,7 +748,9 @@ class UrlIntelAsync(ServiceBaseAsync):
736
748
  """
737
749
 
738
750
  input = m.URLReputationBulkRequest(urls=urls, provider=provider, verbose=verbose, raw=raw)
739
- return await self.request.post("v2/reputation", m.URLReputationBulkResult, data=input.dict(exclude_none=True))
751
+ return await self.request.post(
752
+ "v2/reputation", m.URLReputationBulkResult, data=input.model_dump(exclude_none=True)
753
+ )
740
754
 
741
755
 
742
756
  class UserIntelAsync(ServiceBaseAsync):
@@ -776,6 +790,7 @@ class UserIntelAsync(ServiceBaseAsync):
776
790
  verbose: Optional[bool] = None,
777
791
  raw: Optional[bool] = None,
778
792
  provider: Optional[str] = None,
793
+ cursor: Optional[str] = None,
779
794
  ) -> PangeaResponse[m.UserBreachedResult]:
780
795
  """
781
796
  Look up breached users
@@ -793,7 +808,8 @@ class UserIntelAsync(ServiceBaseAsync):
793
808
  end (str): Latest date for search
794
809
  verbose (bool, optional): Echo the API parameters in the response
795
810
  raw (bool, optional): Include raw data from this provider
796
- provider (str, optional): Use reputation data from this provider: "crowdstrike"
811
+ provider (str, optional): Use reputation data from this provider
812
+ cursor (str, optional): A token given in the raw response from SpyCloud. Post this back to paginate results
797
813
 
798
814
  Raises:
799
815
  PangeaAPIException: If an API Error happens
@@ -821,8 +837,11 @@ class UserIntelAsync(ServiceBaseAsync):
821
837
  end=end,
822
838
  verbose=verbose,
823
839
  raw=raw,
840
+ cursor=cursor,
841
+ )
842
+ return await self.request.post(
843
+ "v1/user/breached", m.UserBreachedResult, data=input.model_dump(exclude_none=True)
824
844
  )
825
- return await self.request.post("v1/user/breached", m.UserBreachedResult, data=input.dict(exclude_none=True))
826
845
 
827
846
  async def user_breached_bulk(
828
847
  self,
@@ -830,6 +849,7 @@ class UserIntelAsync(ServiceBaseAsync):
830
849
  usernames: Optional[List[str]] = None,
831
850
  ips: Optional[List[str]] = None,
832
851
  phone_numbers: Optional[List[str]] = None,
852
+ domains: Optional[List[str]] = None,
833
853
  start: Optional[str] = None,
834
854
  end: Optional[str] = None,
835
855
  verbose: Optional[bool] = None,
@@ -848,11 +868,12 @@ class UserIntelAsync(ServiceBaseAsync):
848
868
  usernames (List[str]): An username's list to search for
849
869
  ips (List[str]): An ip's list to search for
850
870
  phone_numbers (List[str]): A phone number's list to search for. minLength: 7, maxLength: 15.
871
+ domains (List[str]): Search for user under these domains.
851
872
  start (str): Earliest date for search
852
873
  end (str): Latest date for search
853
874
  verbose (bool, optional): Echo the API parameters in the response
854
875
  raw (bool, optional): Include raw data from this provider
855
- provider (str, optional): Use reputation data from this provider: "crowdstrike"
876
+ provider (str, optional): Use reputation data from this provider
856
877
 
857
878
  Raises:
858
879
  PangeaAPIException: If an API Error happens
@@ -870,13 +891,16 @@ class UserIntelAsync(ServiceBaseAsync):
870
891
  phone_numbers=phone_numbers,
871
892
  usernames=usernames,
872
893
  ips=ips,
894
+ domains=domains,
873
895
  provider=provider,
874
896
  start=start,
875
897
  end=end,
876
898
  verbose=verbose,
877
899
  raw=raw,
878
900
  )
879
- return await self.request.post("v2/user/breached", m.UserBreachedBulkResult, data=input.dict(exclude_none=True))
901
+ return await self.request.post(
902
+ "v2/user/breached", m.UserBreachedBulkResult, data=input.model_dump(exclude_none=True)
903
+ )
880
904
 
881
905
  async def password_breached(
882
906
  self,
@@ -898,7 +922,7 @@ class UserIntelAsync(ServiceBaseAsync):
898
922
  hash_prefix (str): The prefix of the hash to be looked up.
899
923
  verbose (bool, optional): Echo the API parameters in the response
900
924
  raw (bool, optional): Include raw data from this provider
901
- provider (str, optional): Use reputation data from this provider: "crowdstrike"
925
+ provider (str, optional): Use reputation data from this provider
902
926
 
903
927
  Raises:
904
928
  PangeaAPIException: If an API Error happens
@@ -919,7 +943,7 @@ class UserIntelAsync(ServiceBaseAsync):
919
943
  hash_type=hash_type, hash_prefix=hash_prefix, provider=provider, verbose=verbose, raw=raw
920
944
  )
921
945
  return await self.request.post(
922
- "v1/password/breached", m.UserPasswordBreachedResult, data=input.dict(exclude_none=True)
946
+ "v1/password/breached", m.UserPasswordBreachedResult, data=input.model_dump(exclude_none=True)
923
947
  )
924
948
 
925
949
  async def password_breached_bulk(
@@ -942,7 +966,7 @@ class UserIntelAsync(ServiceBaseAsync):
942
966
  hash_prefixes (List[str]): The list of prefixes of the hash to be looked up.
943
967
  verbose (bool, optional): Echo the API parameters in the response
944
968
  raw (bool, optional): Include raw data from this provider
945
- provider (str, optional): Use reputation data from this provider: "crowdstrike"
969
+ provider (str, optional): Use reputation data from this provider
946
970
 
947
971
  Raises:
948
972
  PangeaAPIException: If an API Error happens
@@ -959,5 +983,55 @@ class UserIntelAsync(ServiceBaseAsync):
959
983
  hash_type=hash_type, hash_prefixes=hash_prefixes, provider=provider, verbose=verbose, raw=raw
960
984
  )
961
985
  return await self.request.post(
962
- "v2/password/breached", m.UserPasswordBreachedBulkResult, data=input.dict(exclude_none=True)
986
+ "v2/password/breached", m.UserPasswordBreachedBulkResult, data=input.model_dump(exclude_none=True)
987
+ )
988
+
989
+ async def breach(
990
+ self,
991
+ breach_id: str,
992
+ verbose: Optional[bool] = None,
993
+ provider: Optional[str] = None,
994
+ cursor: Optional[str] = None,
995
+ start: Optional[str] = None,
996
+ end: Optional[str] = None,
997
+ severity: Optional[List[int]] = None,
998
+ ) -> PangeaResponse[m.BreachResult]:
999
+ """
1000
+ Look up information about a specific breach
1001
+
1002
+ Given a provider specific breach ID, find details about the breach.
1003
+
1004
+ OperationId: user_intel_post_v1_breach
1005
+
1006
+ Args:
1007
+ breach_id (str, optional): The ID of a breach returned by a provider
1008
+ verbose (bool, optional): Echo the API parameters in the response
1009
+ provider (str, optional): Use reputation data from this provider
1010
+ cursor (str, optional): A token given in the raw response from SpyCloud. Post this back to paginate results
1011
+ start (str, optional): This parameter allows you to define the starting point for a date range query on the spycloud_publish_date field
1012
+ end (str, optional): This parameter allows you to define the ending point for a date range query on the spycloud_publish_date field
1013
+ severity (List[int], optional): Filter for records that match one of the given severities
1014
+
1015
+ Raises:
1016
+ PangeaAPIException: If an API Error happens
1017
+
1018
+ Returns:
1019
+ A PangeaResponse where the breach details are in the
1020
+ response.result field. Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/user-intel)
1021
+
1022
+ Examples:
1023
+ response = await user_intel.breach(
1024
+ breach_id="66111",
1025
+ )
1026
+ """
1027
+
1028
+ input = m.BreachRequest(
1029
+ breach_id=breach_id,
1030
+ provider=provider,
1031
+ verbose=verbose,
1032
+ cursor=cursor,
1033
+ start=start,
1034
+ end=end,
1035
+ severity=severity,
963
1036
  )
1037
+ return await self.request.post("v1/breach", m.BreachResult, data=input.model_dump(exclude_none=True))
@@ -0,0 +1,73 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING
4
+
5
+ from pangea.asyncio.services.base import ServiceBaseAsync
6
+ from pangea.config import PangeaConfig
7
+ from pangea.services.prompt_guard import GuardResult, Message
8
+
9
+ if TYPE_CHECKING:
10
+ from collections.abc import Iterable
11
+
12
+ from pangea.response import PangeaResponse
13
+
14
+
15
+ class PromptGuardAsync(ServiceBaseAsync):
16
+ """Prompt Guard service client.
17
+
18
+ Provides methods to interact with Pangea's Prompt Guard service.
19
+
20
+ Examples:
21
+ from pangea import PangeaConfig
22
+ from pangea.asyncio.services import PromptGuardAsync
23
+
24
+ config = PangeaConfig(domain="aws.us.pangea.cloud")
25
+ prompt_guard = PromptGuardAsync(token="pangea_token", config=config)
26
+ """
27
+
28
+ service_name = "prompt-guard"
29
+
30
+ def __init__(
31
+ self, token: str, config: PangeaConfig | None = None, logger_name: str = "pangea", config_id: str | None = None
32
+ ) -> None:
33
+ """
34
+ Prompt Guard service client.
35
+
36
+ Initializes a new Prompt Guard client.
37
+
38
+ Args:
39
+ token: Pangea API token.
40
+ config: Pangea service configuration.
41
+ logger_name: Logger name.
42
+ config_id: Configuration ID.
43
+
44
+ Examples:
45
+ from pangea import PangeaConfig
46
+ from pangea.asyncio.services import PromptGuardAsync
47
+
48
+ config = PangeaConfig(domain="aws.us.pangea.cloud")
49
+ prompt_guard = PromptGuardAsync(token="pangea_token", config=config)
50
+ """
51
+
52
+ super().__init__(token, config, logger_name, config_id)
53
+
54
+ async def guard(self, messages: Iterable[Message]) -> PangeaResponse[GuardResult]:
55
+ """
56
+ Guard (Beta)
57
+
58
+ Guard messages.
59
+
60
+ How to install a [Beta release](https://pangea.cloud/docs/sdk/python/#beta-releases).
61
+
62
+ OperationId: prompt_guard_post_v1beta_guard
63
+
64
+ Args:
65
+ messages: Messages.
66
+
67
+ Examples:
68
+ from pangea.asyncio.services.prompt_guard import Message
69
+
70
+ response = await prompt_guard.guard([Message(role="user", content="hello world")])
71
+ """
72
+
73
+ return await self.request.post("v1beta/guard", GuardResult, data={"messages": messages})
@@ -1,10 +1,12 @@
1
1
  # Copyright 2022 Pangea Cyber Corporation
2
2
  # Author: Pangea Cyber Corporation
3
+ from __future__ import annotations
3
4
 
4
5
  from typing import Dict, List, Optional, Union
5
6
 
6
7
  import pangea.services.redact as m
7
8
  from pangea.asyncio.services.base import ServiceBaseAsync
9
+ from pangea.config import PangeaConfig
8
10
  from pangea.response import PangeaResponse
9
11
 
10
12
 
@@ -35,7 +37,24 @@ class RedactAsync(ServiceBaseAsync):
35
37
 
36
38
  service_name = "redact"
37
39
 
38
- def __init__(self, token, config=None, logger_name="pangea", config_id: Optional[str] = None):
40
+ def __init__(
41
+ self, token: str, config: PangeaConfig | None = None, logger_name: str = "pangea", config_id: str | None = None
42
+ ) -> None:
43
+ """
44
+ Redact client
45
+
46
+ Initializes a new Redact client.
47
+
48
+ Args:
49
+ token: Pangea API token.
50
+ config: Configuration.
51
+ logger_name: Logger name.
52
+
53
+ Examples:
54
+ config = PangeaConfig(domain="pangea_domain")
55
+ redact = RedactAsync(token="pangea_token", config=config)
56
+ """
57
+
39
58
  super().__init__(token, config, logger_name, config_id=config_id)
40
59
 
41
60
  async def redact(
@@ -45,6 +64,9 @@ class RedactAsync(ServiceBaseAsync):
45
64
  rules: Optional[List[str]] = None,
46
65
  rulesets: Optional[List[str]] = None,
47
66
  return_result: Optional[bool] = None,
67
+ redaction_method_overrides: Optional[m.RedactionMethodOverrides] = None,
68
+ llm_request: Optional[bool] = None,
69
+ vault_parameters: Optional[m.VaultParameters] = None,
48
70
  ) -> PangeaResponse[m.RedactResult]:
49
71
  """
50
72
  Redact
@@ -60,6 +82,9 @@ class RedactAsync(ServiceBaseAsync):
60
82
  rules (list[str], optional): An array of redact rule short names
61
83
  rulesets (list[str], optional): An array of redact rulesets short names
62
84
  return_result(bool, optional): Setting this value to false will omit the redacted result only returning count
85
+ redaction_method_overrides: A set of redaction method overrides for any enabled rule. These methods override the config declared methods
86
+ llm_request: Boolean flag to enable FPE redaction for LLM requests
87
+ vault_parameters: A set of vault parameters to use for redaction
63
88
 
64
89
  Raises:
65
90
  PangeaAPIException: If an API Error happens
@@ -73,8 +98,17 @@ class RedactAsync(ServiceBaseAsync):
73
98
  response = redact.redact(text="Jenny Jenny... 555-867-5309")
74
99
  """
75
100
 
76
- input = m.RedactRequest(text=text, debug=debug, rules=rules, rulesets=rulesets, return_result=return_result)
77
- return await self.request.post("v1/redact", m.RedactResult, data=input.dict(exclude_none=True))
101
+ input = m.RedactRequest(
102
+ text=text,
103
+ debug=debug,
104
+ rules=rules,
105
+ rulesets=rulesets,
106
+ return_result=return_result,
107
+ redaction_method_overrides=redaction_method_overrides,
108
+ llm_request=llm_request,
109
+ vault_parameters=vault_parameters,
110
+ )
111
+ return await self.request.post("v1/redact", m.RedactResult, data=input.model_dump(exclude_none=True))
78
112
 
79
113
  async def redact_structured(
80
114
  self,
@@ -85,6 +119,9 @@ class RedactAsync(ServiceBaseAsync):
85
119
  rules: Optional[List[str]] = None,
86
120
  rulesets: Optional[List[str]] = None,
87
121
  return_result: Optional[bool] = None,
122
+ redaction_method_overrides: Optional[m.RedactionMethodOverrides] = None,
123
+ llm_request: bool | None = None,
124
+ vault_parameters: m.VaultParameters | None = None,
88
125
  ) -> PangeaResponse[m.StructuredResult]:
89
126
  """
90
127
  Redact structured
@@ -104,6 +141,9 @@ class RedactAsync(ServiceBaseAsync):
104
141
  rules (list[str], optional): An array of redact rule short names
105
142
  rulesets (list[str], optional): An array of redact rulesets short names
106
143
  return_result(bool, optional): Setting this value to false will omit the redacted result only returning count
144
+ redaction_method_overrides: A set of redaction method overrides for any enabled rule. These methods override the config declared methods
145
+ llm_request: Boolean flag to enable FPE redaction for LLM requests
146
+ vault_parameters: A set of vault parameters to use for redaction
107
147
 
108
148
  Raises:
109
149
  PangeaAPIException: If an API Error happens
@@ -130,5 +170,33 @@ class RedactAsync(ServiceBaseAsync):
130
170
  rules=rules,
131
171
  rulesets=rulesets,
132
172
  return_result=return_result,
173
+ redaction_method_overrides=redaction_method_overrides,
174
+ llm_request=llm_request,
175
+ vault_parameters=vault_parameters,
176
+ )
177
+ return await self.request.post(
178
+ "v1/redact_structured", m.StructuredResult, data=input.model_dump(exclude_none=True)
133
179
  )
134
- return await self.request.post("v1/redact_structured", m.StructuredResult, data=input.dict(exclude_none=True))
180
+
181
+ async def unredact(self, redacted_data: m.RedactedData, fpe_context: str) -> PangeaResponse[m.UnredactResult]:
182
+ """
183
+ Unredact
184
+
185
+ Decrypt or unredact fpe redactions
186
+
187
+ OperationId: redact_post_v1_unredact
188
+
189
+ Args:
190
+ redacted_data: Data to unredact
191
+ fpe_context (base64): FPE context used to decrypt and unredact data
192
+
193
+ Raises:
194
+ PangeaAPIException: If an API Error happens
195
+
196
+ Returns:
197
+ Pangea Response with redacted data in the response.result field,
198
+ available response fields can be found in our
199
+ [API Documentation](https://pangea.cloud/docs/api/redact#unredact)
200
+ """
201
+ input = m.UnredactRequest(redacted_data=redacted_data, fpe_context=fpe_context)
202
+ return await self.request.post("v1/unredact", m.UnredactResult, data=input.model_dump(exclude_none=True))