pangea-sdk 3.8.0b1__py3-none-any.whl → 5.4.0b1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pangea/__init__.py +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))
         |