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.
- pangea/__init__.py +1 -1
- pangea/asyncio/file_uploader.py +1 -1
- pangea/asyncio/request.py +56 -34
- pangea/asyncio/services/__init__.py +4 -0
- pangea/asyncio/services/ai_guard.py +75 -0
- pangea/asyncio/services/audit.py +192 -31
- pangea/asyncio/services/authn.py +187 -109
- pangea/asyncio/services/authz.py +285 -0
- pangea/asyncio/services/base.py +21 -2
- pangea/asyncio/services/embargo.py +2 -2
- pangea/asyncio/services/file_scan.py +24 -9
- pangea/asyncio/services/intel.py +108 -34
- pangea/asyncio/services/prompt_guard.py +73 -0
- pangea/asyncio/services/redact.py +72 -4
- pangea/asyncio/services/sanitize.py +217 -0
- pangea/asyncio/services/share.py +246 -73
- pangea/asyncio/services/vault.py +1710 -750
- pangea/crypto/rsa.py +135 -0
- pangea/deep_verify.py +7 -1
- pangea/dump_audit.py +9 -8
- pangea/request.py +87 -59
- pangea/response.py +49 -31
- pangea/services/__init__.py +4 -0
- pangea/services/ai_guard.py +128 -0
- pangea/services/audit/audit.py +205 -42
- pangea/services/audit/models.py +56 -8
- pangea/services/audit/signing.py +6 -5
- pangea/services/audit/util.py +3 -3
- pangea/services/authn/authn.py +140 -70
- pangea/services/authn/models.py +167 -11
- pangea/services/authz.py +400 -0
- pangea/services/base.py +39 -8
- pangea/services/embargo.py +2 -2
- pangea/services/file_scan.py +32 -15
- pangea/services/intel.py +157 -32
- pangea/services/prompt_guard.py +83 -0
- pangea/services/redact.py +152 -4
- pangea/services/sanitize.py +371 -0
- pangea/services/share/share.py +683 -107
- pangea/services/vault/models/asymmetric.py +120 -18
- pangea/services/vault/models/common.py +439 -141
- pangea/services/vault/models/keys.py +94 -0
- pangea/services/vault/models/secret.py +27 -3
- pangea/services/vault/models/symmetric.py +68 -22
- pangea/services/vault/vault.py +1690 -749
- pangea/tools.py +6 -7
- pangea/utils.py +16 -27
- pangea/verify_audit.py +270 -83
- {pangea_sdk-3.8.0b1.dist-info → pangea_sdk-5.4.0b1.dist-info}/METADATA +43 -35
- pangea_sdk-5.4.0b1.dist-info/RECORD +60 -0
- {pangea_sdk-3.8.0b1.dist-info → pangea_sdk-5.4.0b1.dist-info}/WHEEL +1 -1
- pangea_sdk-3.8.0b1.dist-info/RECORD +0 -50
pangea/asyncio/services/intel.py
CHANGED
@@ -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(
|
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.
|
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(
|
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(
|
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(
|
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(
|
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.
|
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.
|
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.
|
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
|
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.
|
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.
|
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
|
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(
|
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.
|
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(
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
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
|
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.
|
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
|
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(
|
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
|
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
|
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(
|
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
|
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.
|
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
|
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.
|
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__(
|
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(
|
77
|
-
|
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
|
-
|
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))
|