pangea-sdk 5.5.0b4__py3-none-any.whl → 6.0.0__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/services/ai_guard.py +7 -56
- pangea/asyncio/services/audit.py +0 -5
- pangea/config.py +23 -25
- pangea/request.py +6 -15
- pangea/services/ai_guard.py +192 -58
- pangea/services/audit/audit.py +0 -4
- pangea/services/prompt_guard.py +2 -2
- pangea/services/redact.py +8 -3
- pangea/tools.py +6 -9
- {pangea_sdk-5.5.0b4.dist-info → pangea_sdk-6.0.0.dist-info}/METADATA +12 -13
- {pangea_sdk-5.5.0b4.dist-info → pangea_sdk-6.0.0.dist-info}/RECORD +13 -13
- {pangea_sdk-5.5.0b4.dist-info → pangea_sdk-6.0.0.dist-info}/WHEEL +1 -1
pangea/__init__.py
CHANGED
@@ -7,7 +7,7 @@ from typing_extensions import TypeVar
|
|
7
7
|
from pangea.asyncio.services.base import ServiceBaseAsync
|
8
8
|
from pangea.config import PangeaConfig
|
9
9
|
from pangea.response import PangeaResponse
|
10
|
-
from pangea.services.ai_guard import LogFields, TextGuardResult
|
10
|
+
from pangea.services.ai_guard import LogFields, Overrides, TextGuardResult
|
11
11
|
|
12
12
|
_T = TypeVar("_T")
|
13
13
|
|
@@ -58,7 +58,7 @@ class AIGuardAsync(ServiceBaseAsync):
|
|
58
58
|
*,
|
59
59
|
recipe: str | None = None,
|
60
60
|
debug: bool | None = None,
|
61
|
-
|
61
|
+
overrides: Overrides | None = None,
|
62
62
|
log_fields: LogFields | None = None,
|
63
63
|
) -> PangeaResponse[TextGuardResult[None]]:
|
64
64
|
"""
|
@@ -78,7 +78,6 @@ class AIGuardAsync(ServiceBaseAsync):
|
|
78
78
|
are to be applied to the text, such as defang malicious URLs.
|
79
79
|
debug: Setting this value to true will provide a detailed analysis
|
80
80
|
of the text data
|
81
|
-
llm_info: Short string hint for the LLM Provider information
|
82
81
|
log_field: Additional fields to include in activity log
|
83
82
|
|
84
83
|
Examples:
|
@@ -92,7 +91,7 @@ class AIGuardAsync(ServiceBaseAsync):
|
|
92
91
|
messages: _T,
|
93
92
|
recipe: str | None = None,
|
94
93
|
debug: bool | None = None,
|
95
|
-
|
94
|
+
overrides: Overrides | None = None,
|
96
95
|
log_fields: LogFields | None = None,
|
97
96
|
) -> PangeaResponse[TextGuardResult[_T]]:
|
98
97
|
"""
|
@@ -113,59 +112,20 @@ class AIGuardAsync(ServiceBaseAsync):
|
|
113
112
|
are to be applied to the text, such as defang malicious URLs.
|
114
113
|
debug: Setting this value to true will provide a detailed analysis
|
115
114
|
of the text data
|
116
|
-
llm_info: Short string hint for the LLM Provider information
|
117
115
|
log_field: Additional fields to include in activity log
|
118
116
|
|
119
117
|
Examples:
|
120
118
|
response = await ai_guard.guard_text(messages=[{"role": "user", "content": "hello world"}])
|
121
119
|
"""
|
122
120
|
|
123
|
-
@overload
|
124
|
-
async def guard_text(
|
125
|
-
self,
|
126
|
-
*,
|
127
|
-
llm_input: _T,
|
128
|
-
recipe: str | None = None,
|
129
|
-
debug: bool | None = None,
|
130
|
-
llm_info: str | None = None,
|
131
|
-
log_fields: LogFields | None = None,
|
132
|
-
) -> PangeaResponse[TextGuardResult[_T]]:
|
133
|
-
"""
|
134
|
-
Text Guard for scanning LLM inputs and outputs
|
135
|
-
|
136
|
-
Analyze and redact text to avoid manipulation of the model, addition of
|
137
|
-
malicious content, and other undesirable data transfers.
|
138
|
-
|
139
|
-
OperationId: ai_guard_post_v1_text_guard
|
140
|
-
|
141
|
-
Args:
|
142
|
-
llm_input: Structured full llm payload data to be scanned by AI
|
143
|
-
Guard for PII, sensitive data, malicious content, and other data
|
144
|
-
types defined by the configuration. Supports processing up to
|
145
|
-
10KB of JSON text
|
146
|
-
recipe: Recipe key of a configuration of data types and settings
|
147
|
-
defined in the Pangea User Console. It specifies the rules that
|
148
|
-
are to be applied to the text, such as defang malicious URLs.
|
149
|
-
debug: Setting this value to true will provide a detailed analysis
|
150
|
-
of the text data
|
151
|
-
llm_info: Short string hint for the LLM Provider information
|
152
|
-
log_field: Additional fields to include in activity log
|
153
|
-
|
154
|
-
Examples:
|
155
|
-
response = await ai_guard.guard_text(
|
156
|
-
llm_input={"model": "gpt-4o", "messages": [{"role": "user", "content": "hello world"}]}
|
157
|
-
)
|
158
|
-
"""
|
159
|
-
|
160
121
|
async def guard_text( # type: ignore[misc]
|
161
122
|
self,
|
162
123
|
text: str | None = None,
|
163
124
|
*,
|
164
125
|
messages: _T | None = None,
|
165
|
-
llm_input: _T | None = None,
|
166
126
|
recipe: str | None = None,
|
167
127
|
debug: bool | None = None,
|
168
|
-
|
128
|
+
overrides: Overrides | None = None,
|
169
129
|
log_fields: LogFields | None = None,
|
170
130
|
) -> PangeaResponse[TextGuardResult[None]]:
|
171
131
|
"""
|
@@ -184,27 +144,19 @@ class AIGuardAsync(ServiceBaseAsync):
|
|
184
144
|
PII, sensitive data, malicious content, and other data types
|
185
145
|
defined by the configuration. Supports processing up to 10KB of
|
186
146
|
JSON text
|
187
|
-
llm_input: Structured full llm payload data to be scanned by AI
|
188
|
-
Guard for PII, sensitive data, malicious content, and other data
|
189
|
-
types defined by the configuration. Supports processing up to
|
190
|
-
10KB of JSON text
|
191
147
|
recipe: Recipe key of a configuration of data types and settings
|
192
148
|
defined in the Pangea User Console. It specifies the rules that
|
193
149
|
are to be applied to the text, such as defang malicious URLs.
|
194
150
|
debug: Setting this value to true will provide a detailed analysis
|
195
151
|
of the text data
|
196
|
-
llm_info: Short string hint for the LLM Provider information
|
197
152
|
log_field: Additional fields to include in activity log
|
198
153
|
|
199
154
|
Examples:
|
200
155
|
response = await ai_guard.guard_text("text")
|
201
156
|
"""
|
202
157
|
|
203
|
-
if not
|
204
|
-
raise ValueError("Exactly one of `text
|
205
|
-
|
206
|
-
if sum((text is not None, messages is not None, llm_input is not None)) > 1:
|
207
|
-
raise ValueError("Only one of `text`, `messages`, or `llm_input` can be given at once")
|
158
|
+
if text is not None and messages is not None:
|
159
|
+
raise ValueError("Exactly one of `text` or `messages` must be given")
|
208
160
|
|
209
161
|
return await self.request.post(
|
210
162
|
"v1/text/guard",
|
@@ -212,10 +164,9 @@ class AIGuardAsync(ServiceBaseAsync):
|
|
212
164
|
data={
|
213
165
|
"text": text,
|
214
166
|
"messages": messages,
|
215
|
-
"llm_input": llm_input,
|
216
167
|
"recipe": recipe,
|
217
168
|
"debug": debug,
|
218
|
-
"
|
169
|
+
"overrides": overrides,
|
219
170
|
"log_fields": log_fields,
|
220
171
|
},
|
221
172
|
)
|
pangea/asyncio/services/audit.py
CHANGED
@@ -86,11 +86,6 @@ class AuditAsync(ServiceBaseAsync, AuditBase):
|
|
86
86
|
config = PangeaConfig(domain="pangea_domain")
|
87
87
|
audit = AuditAsync(token="pangea_token", config=config)
|
88
88
|
"""
|
89
|
-
|
90
|
-
# FIXME: Temporary check to deprecate config_id from PangeaConfig.
|
91
|
-
# Delete it when deprecate PangeaConfig.config_id
|
92
|
-
if config_id and config is not None and config.config_id is not None:
|
93
|
-
config_id = config.config_id
|
94
89
|
ServiceBaseAsync.__init__(self, token, config=config, logger_name=logger_name, config_id=config_id)
|
95
90
|
AuditBase.__init__(
|
96
91
|
self, private_key_file=private_key_file, public_key_info=public_key_info, tenant_id=tenant_id
|
pangea/config.py
CHANGED
@@ -1,39 +1,30 @@
|
|
1
1
|
# Copyright 2022 Pangea Cyber Corporation
|
2
2
|
# Author: Pangea Cyber Corporation
|
3
|
+
from __future__ import annotations
|
3
4
|
|
4
|
-
from
|
5
|
-
from typing import Literal, Optional
|
5
|
+
from typing import Any, Optional
|
6
6
|
|
7
|
+
from pydantic import BaseModel, model_validator
|
7
8
|
|
8
|
-
@dataclass
|
9
|
-
class PangeaConfig:
|
10
|
-
"""Holds run time configuration information used by SDK components."""
|
11
|
-
|
12
|
-
domain: str = "aws.us.pangea.cloud"
|
13
|
-
"""
|
14
|
-
Used to set Pangea domain (and port if needed), it should not include service subdomain
|
15
|
-
just for particular use cases when environment = "local", domain could be set to an url including:
|
16
|
-
scheme (http:// or https://), subdomain, domain and port.
|
17
|
-
"""
|
18
|
-
|
19
|
-
environment: Literal["production", "local"] = "production"
|
20
|
-
"""
|
21
|
-
Pangea environment, used to construct service URLs.
|
22
9
|
|
23
|
-
|
24
|
-
|
25
|
-
"""
|
10
|
+
class PangeaConfig(BaseModel):
|
11
|
+
"""Holds run time configuration information used by SDK components."""
|
26
12
|
|
27
|
-
|
13
|
+
base_url_template: str = "https://{SERVICE_NAME}.aws.us.pangea.cloud"
|
28
14
|
"""
|
29
|
-
|
30
|
-
|
31
|
-
|
15
|
+
Template for constructing the base URL for API requests. The placeholder
|
16
|
+
`{SERVICE_NAME}` will be replaced with the service name slug. This is a
|
17
|
+
more powerful version of `domain` that allows for setting more than just
|
18
|
+
the host of the API server. Defaults to
|
19
|
+
`https://{SERVICE_NAME}.aws.us.pangea.cloud`.
|
32
20
|
"""
|
33
21
|
|
34
|
-
|
22
|
+
domain: str = "aws.us.pangea.cloud"
|
35
23
|
"""
|
36
|
-
|
24
|
+
Base domain for API requests. This is a weaker version of `base_url_template`
|
25
|
+
that only allows for setting the host of the API server. Use
|
26
|
+
`base_url_template` for more control over the URL, such as setting
|
27
|
+
service-specific paths. Defaults to `aws.us.pangea.cloud`.
|
37
28
|
"""
|
38
29
|
|
39
30
|
request_retries: int = 3
|
@@ -65,3 +56,10 @@ class PangeaConfig:
|
|
65
56
|
"""
|
66
57
|
Extra user agent to be added to request user agent
|
67
58
|
"""
|
59
|
+
|
60
|
+
@model_validator(mode="before")
|
61
|
+
@classmethod
|
62
|
+
def _domain_backwards_compat(cls, data: Any) -> Any:
|
63
|
+
if isinstance(data, dict) and "base_url_template" not in data and "domain" in data:
|
64
|
+
return {**data, "base_url_template": f"https://{{SERVICE_NAME}}.{data['domain']}"}
|
65
|
+
return data
|
pangea/request.py
CHANGED
@@ -14,6 +14,7 @@ from pydantic_core import to_jsonable_python
|
|
14
14
|
from requests.adapters import HTTPAdapter, Retry
|
15
15
|
from requests_toolbelt import MultipartDecoder # type: ignore[import-untyped]
|
16
16
|
from typing_extensions import TypeVar
|
17
|
+
from yarl import URL
|
17
18
|
|
18
19
|
import pangea
|
19
20
|
import pangea.exceptions as pe
|
@@ -107,16 +108,8 @@ class PangeaRequestBase:
|
|
107
108
|
return f"request/{request_id}"
|
108
109
|
|
109
110
|
def _url(self, path: str) -> str:
|
110
|
-
|
111
|
-
|
112
|
-
url = f"{self.config.domain}/{path}"
|
113
|
-
else:
|
114
|
-
schema = "http://" if self.config.insecure else "https://"
|
115
|
-
domain = (
|
116
|
-
self.config.domain if self.config.environment == "local" else f"{self.service}.{self.config.domain}"
|
117
|
-
)
|
118
|
-
url = f"{schema}{domain}/{path}"
|
119
|
-
return url
|
111
|
+
url = URL(self.config.base_url_template.format(SERVICE_NAME=self.service))
|
112
|
+
return str(url / path)
|
120
113
|
|
121
114
|
def _headers(self) -> dict:
|
122
115
|
headers = {
|
@@ -124,7 +117,7 @@ class PangeaRequestBase:
|
|
124
117
|
"Authorization": f"Bearer {self.token}",
|
125
118
|
}
|
126
119
|
|
127
|
-
# We want to ignore previous headers if user
|
120
|
+
# We want to ignore previous headers if user tried to set them, so we will overwrite them.
|
128
121
|
self._extra_headers.update(headers)
|
129
122
|
return self._extra_headers
|
130
123
|
|
@@ -628,9 +621,7 @@ class PangeaRequest(PangeaRequestBase):
|
|
628
621
|
adapter = HTTPAdapter(max_retries=retry_config)
|
629
622
|
session = requests.Session()
|
630
623
|
|
631
|
-
|
632
|
-
|
633
|
-
else:
|
634
|
-
session.mount("https://", adapter)
|
624
|
+
session.mount("http://", adapter)
|
625
|
+
session.mount("https://", adapter)
|
635
626
|
|
636
627
|
return session
|
pangea/services/ai_guard.py
CHANGED
@@ -1,11 +1,155 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
|
3
|
-
from typing import Any, Dict, Generic, List, Optional, TypeVar, overload
|
3
|
+
from typing import Any, Dict, Generic, List, Literal, Optional, TypeVar, overload
|
4
4
|
|
5
5
|
from pangea.config import PangeaConfig
|
6
6
|
from pangea.response import APIRequestModel, APIResponseModel, PangeaResponse, PangeaResponseResult
|
7
7
|
from pangea.services.base import ServiceBase
|
8
8
|
|
9
|
+
# This is named "prompt injection" in the API spec even though it is also used
|
10
|
+
# for many other detectors.
|
11
|
+
PromptInjectionAction = Literal["report", "block"]
|
12
|
+
|
13
|
+
MaliciousEntityAction = Literal["report", "defang", "disabled", "block"]
|
14
|
+
|
15
|
+
# This is named "PII entity" in the API spec even though it is also used for the
|
16
|
+
# secrets detector.
|
17
|
+
PiiEntityAction = Literal["disabled", "report", "block", "mask", "partial_masking", "replacement", "hash", "fpe"]
|
18
|
+
|
19
|
+
|
20
|
+
class CodeDetectionOverride(APIRequestModel):
|
21
|
+
disabled: Optional[bool] = None
|
22
|
+
action: Optional[Literal["report", "block"]] = None
|
23
|
+
|
24
|
+
|
25
|
+
class LanguageDetectionOverride(APIRequestModel):
|
26
|
+
disabled: Optional[bool] = None
|
27
|
+
allow: Optional[List[str]] = None
|
28
|
+
block: Optional[List[str]] = None
|
29
|
+
report: Optional[List[str]] = None
|
30
|
+
|
31
|
+
|
32
|
+
class TopicDetectionOverride(APIRequestModel):
|
33
|
+
disabled: Optional[bool] = None
|
34
|
+
block: Optional[List[str]] = None
|
35
|
+
|
36
|
+
|
37
|
+
class PromptInjectionOverride(APIRequestModel):
|
38
|
+
disabled: Optional[bool] = None
|
39
|
+
action: Optional[PromptInjectionAction] = None
|
40
|
+
|
41
|
+
|
42
|
+
class SelfHarmOverride(APIRequestModel):
|
43
|
+
disabled: Optional[bool] = None
|
44
|
+
action: Optional[PromptInjectionAction] = None
|
45
|
+
threshold: Optional[float] = None
|
46
|
+
|
47
|
+
|
48
|
+
class GibberishOverride(APIRequestModel):
|
49
|
+
disabled: Optional[bool] = None
|
50
|
+
action: Optional[PromptInjectionAction] = None
|
51
|
+
|
52
|
+
|
53
|
+
class RoleplayOverride(APIRequestModel):
|
54
|
+
disabled: Optional[bool] = None
|
55
|
+
action: Optional[PromptInjectionAction] = None
|
56
|
+
|
57
|
+
|
58
|
+
class SentimentOverride(APIRequestModel):
|
59
|
+
disabled: Optional[bool] = None
|
60
|
+
action: Optional[PromptInjectionAction] = None
|
61
|
+
threshold: Optional[float] = None
|
62
|
+
|
63
|
+
|
64
|
+
class MaliciousEntityOverride(APIRequestModel):
|
65
|
+
disabled: Optional[bool] = None
|
66
|
+
ip_address: Optional[MaliciousEntityAction] = None
|
67
|
+
url: Optional[MaliciousEntityAction] = None
|
68
|
+
domain: Optional[MaliciousEntityAction] = None
|
69
|
+
|
70
|
+
|
71
|
+
class CompetitorsOverride(APIRequestModel):
|
72
|
+
disabled: Optional[bool] = None
|
73
|
+
action: Optional[PromptInjectionAction] = None
|
74
|
+
|
75
|
+
|
76
|
+
class PiiEntityOverride(APIRequestModel):
|
77
|
+
disabled: Optional[bool] = None
|
78
|
+
email_address: Optional[PiiEntityAction] = None
|
79
|
+
nrp: Optional[PiiEntityAction] = None
|
80
|
+
location: Optional[PiiEntityAction] = None
|
81
|
+
person: Optional[PiiEntityAction] = None
|
82
|
+
phone_number: Optional[PiiEntityAction] = None
|
83
|
+
date_time: Optional[PiiEntityAction] = None
|
84
|
+
ip_address: Optional[PiiEntityAction] = None
|
85
|
+
url: Optional[PiiEntityAction] = None
|
86
|
+
money: Optional[PiiEntityAction] = None
|
87
|
+
credit_card: Optional[PiiEntityAction] = None
|
88
|
+
crypto: Optional[PiiEntityAction] = None
|
89
|
+
iban_code: Optional[PiiEntityAction] = None
|
90
|
+
us_bank_number: Optional[PiiEntityAction] = None
|
91
|
+
nif: Optional[PiiEntityAction] = None
|
92
|
+
au_abn: Optional[PiiEntityAction] = None
|
93
|
+
au_acn: Optional[PiiEntityAction] = None
|
94
|
+
au_tfn: Optional[PiiEntityAction] = None
|
95
|
+
medical_license: Optional[PiiEntityAction] = None
|
96
|
+
uk_nhs: Optional[PiiEntityAction] = None
|
97
|
+
au_medicare: Optional[PiiEntityAction] = None
|
98
|
+
us_drivers_license: Optional[PiiEntityAction] = None
|
99
|
+
us_itin: Optional[PiiEntityAction] = None
|
100
|
+
us_passport: Optional[PiiEntityAction] = None
|
101
|
+
us_ssn: Optional[PiiEntityAction] = None
|
102
|
+
|
103
|
+
|
104
|
+
class SecretsDetectionOverride(APIRequestModel):
|
105
|
+
disabled: Optional[bool] = None
|
106
|
+
slack_token: Optional[PiiEntityAction] = None
|
107
|
+
rsa_private_key: Optional[PiiEntityAction] = None
|
108
|
+
ssh_dsa_private_key: Optional[PiiEntityAction] = None
|
109
|
+
ssh_ec_private_key: Optional[PiiEntityAction] = None
|
110
|
+
pgp_private_key_block: Optional[PiiEntityAction] = None
|
111
|
+
amazon_aws_access_key_id: Optional[PiiEntityAction] = None
|
112
|
+
amazon_aws_secret_access_key: Optional[PiiEntityAction] = None
|
113
|
+
amazon_mws_auth_token: Optional[PiiEntityAction] = None
|
114
|
+
facebook_access_token: Optional[PiiEntityAction] = None
|
115
|
+
github_access_token: Optional[PiiEntityAction] = None
|
116
|
+
jwt_token: Optional[PiiEntityAction] = None
|
117
|
+
google_api_key: Optional[PiiEntityAction] = None
|
118
|
+
google_cloud_platform_api_key: Optional[PiiEntityAction] = None
|
119
|
+
google_drive_api_key: Optional[PiiEntityAction] = None
|
120
|
+
google_cloud_platform_service_account: Optional[PiiEntityAction] = None
|
121
|
+
google_gmail_api_key: Optional[PiiEntityAction] = None
|
122
|
+
youtube_api_key: Optional[PiiEntityAction] = None
|
123
|
+
mailchimp_api_key: Optional[PiiEntityAction] = None
|
124
|
+
mailgun_api_key: Optional[PiiEntityAction] = None
|
125
|
+
basic_auth: Optional[PiiEntityAction] = None
|
126
|
+
picatic_api_key: Optional[PiiEntityAction] = None
|
127
|
+
slack_webhook: Optional[PiiEntityAction] = None
|
128
|
+
stripe_api_key: Optional[PiiEntityAction] = None
|
129
|
+
stripe_restricted_api_key: Optional[PiiEntityAction] = None
|
130
|
+
square_access_token: Optional[PiiEntityAction] = None
|
131
|
+
square_oauth_secret: Optional[PiiEntityAction] = None
|
132
|
+
twilio_api_key: Optional[PiiEntityAction] = None
|
133
|
+
pangea_token: Optional[PiiEntityAction] = None
|
134
|
+
|
135
|
+
|
136
|
+
class Overrides(APIRequestModel):
|
137
|
+
ignore_recipe: Optional[bool] = None
|
138
|
+
"""Bypass existing Recipe content and create an on-the-fly Recipe."""
|
139
|
+
|
140
|
+
code_detection: Optional[CodeDetectionOverride] = None
|
141
|
+
competitors: Optional[CompetitorsOverride] = None
|
142
|
+
gibberish: Optional[GibberishOverride] = None
|
143
|
+
language_detection: Optional[LanguageDetectionOverride] = None
|
144
|
+
malicious_entity: Optional[MaliciousEntityOverride] = None
|
145
|
+
pii_entity: Optional[PiiEntityOverride] = None
|
146
|
+
prompt_injection: Optional[PromptInjectionOverride] = None
|
147
|
+
roleplay: Optional[RoleplayOverride] = None
|
148
|
+
secrets_detection: Optional[SecretsDetectionOverride] = None
|
149
|
+
selfharm: Optional[SelfHarmOverride] = None
|
150
|
+
sentiment: Optional[SentimentOverride] = None
|
151
|
+
topic_detection: Optional[TopicDetectionOverride] = None
|
152
|
+
|
9
153
|
|
10
154
|
class LogFields(APIRequestModel):
|
11
155
|
"""Additional fields to include in activity log"""
|
@@ -33,6 +177,8 @@ class AnalyzerResponse(APIResponseModel):
|
|
33
177
|
|
34
178
|
class PromptInjectionResult(APIResponseModel):
|
35
179
|
action: str
|
180
|
+
"""The action taken by this Detector"""
|
181
|
+
|
36
182
|
analyzer_responses: List[AnalyzerResponse]
|
37
183
|
"""Triggered prompt injection analyzers."""
|
38
184
|
|
@@ -41,11 +187,13 @@ class PiiEntity(APIResponseModel):
|
|
41
187
|
type: str
|
42
188
|
value: str
|
43
189
|
action: str
|
190
|
+
"""The action taken on this Entity"""
|
44
191
|
start_pos: Optional[int] = None
|
45
192
|
|
46
193
|
|
47
194
|
class PiiEntityResult(APIResponseModel):
|
48
195
|
entities: List[PiiEntity]
|
196
|
+
"""Detected redaction rules."""
|
49
197
|
|
50
198
|
|
51
199
|
class MaliciousEntity(APIResponseModel):
|
@@ -58,35 +206,59 @@ class MaliciousEntity(APIResponseModel):
|
|
58
206
|
|
59
207
|
class MaliciousEntityResult(APIResponseModel):
|
60
208
|
entities: List[MaliciousEntity]
|
209
|
+
"""Detected harmful items."""
|
210
|
+
|
211
|
+
|
212
|
+
class CustomEntity(APIResponseModel):
|
213
|
+
type: str
|
214
|
+
value: str
|
215
|
+
action: str
|
216
|
+
"""The action taken on this Entity"""
|
217
|
+
start_pos: Optional[int] = None
|
218
|
+
raw: Optional[Dict[str, Any]] = None
|
219
|
+
|
220
|
+
|
221
|
+
class CustomEntityResult(APIResponseModel):
|
222
|
+
entities: List[CustomEntity]
|
223
|
+
"""Detected redaction rules."""
|
61
224
|
|
62
225
|
|
63
226
|
class SecretsEntity(APIResponseModel):
|
64
227
|
type: str
|
65
228
|
value: str
|
66
229
|
action: str
|
230
|
+
"""The action taken on this Entity"""
|
67
231
|
start_pos: Optional[int] = None
|
68
232
|
redacted_value: Optional[str] = None
|
69
233
|
|
70
234
|
|
71
235
|
class SecretsEntityResult(APIResponseModel):
|
72
236
|
entities: List[SecretsEntity]
|
237
|
+
"""Detected redaction rules."""
|
73
238
|
|
74
239
|
|
75
240
|
class LanguageDetectionResult(APIResponseModel):
|
76
241
|
language: str
|
77
242
|
action: str
|
243
|
+
"""The action taken by this Detector"""
|
244
|
+
|
245
|
+
|
246
|
+
class TopicDetectionResult(APIResponseModel):
|
247
|
+
action: str
|
248
|
+
"""The action taken by this Detector"""
|
78
249
|
|
79
250
|
|
80
251
|
class CodeDetectionResult(APIResponseModel):
|
81
252
|
language: str
|
82
253
|
action: str
|
254
|
+
"""The action taken by this Detector"""
|
83
255
|
|
84
256
|
|
85
257
|
_T = TypeVar("_T")
|
86
258
|
|
87
259
|
|
88
260
|
class TextGuardDetector(APIResponseModel, Generic[_T]):
|
89
|
-
detected: bool
|
261
|
+
detected: Optional[bool] = None
|
90
262
|
data: Optional[_T] = None
|
91
263
|
|
92
264
|
|
@@ -94,10 +266,11 @@ class TextGuardDetectors(APIResponseModel):
|
|
94
266
|
prompt_injection: Optional[TextGuardDetector[PromptInjectionResult]] = None
|
95
267
|
pii_entity: Optional[TextGuardDetector[PiiEntityResult]] = None
|
96
268
|
malicious_entity: Optional[TextGuardDetector[MaliciousEntityResult]] = None
|
269
|
+
custom_entity: Optional[TextGuardDetector[Any]] = None
|
97
270
|
secrets_detection: Optional[TextGuardDetector[SecretsEntityResult]] = None
|
98
271
|
profanity_and_toxicity: Optional[TextGuardDetector[Any]] = None
|
99
|
-
custom_entity: Optional[TextGuardDetector[Any]] = None
|
100
272
|
language_detection: Optional[TextGuardDetector[LanguageDetectionResult]] = None
|
273
|
+
topic_detection: Optional[TextGuardDetector[TopicDetectionResult]] = None
|
101
274
|
code_detection: Optional[TextGuardDetector[CodeDetectionResult]] = None
|
102
275
|
|
103
276
|
|
@@ -112,6 +285,16 @@ class TextGuardResult(PangeaResponseResult, Generic[_T]):
|
|
112
285
|
"""Updated structured prompt, if applicable."""
|
113
286
|
|
114
287
|
blocked: bool
|
288
|
+
"""Whether or not the prompt triggered a block detection."""
|
289
|
+
|
290
|
+
recipe: str
|
291
|
+
"""The Recipe that was used."""
|
292
|
+
|
293
|
+
fpe_context: Optional[str] = None
|
294
|
+
"""
|
295
|
+
If an FPE redaction method returned results, this will be the context passed
|
296
|
+
to unredact.
|
297
|
+
"""
|
115
298
|
|
116
299
|
|
117
300
|
class AIGuard(ServiceBase):
|
@@ -160,7 +343,7 @@ class AIGuard(ServiceBase):
|
|
160
343
|
*,
|
161
344
|
recipe: str | None = None,
|
162
345
|
debug: bool | None = None,
|
163
|
-
|
346
|
+
overrides: Overrides | None = None,
|
164
347
|
log_fields: LogFields | None = None,
|
165
348
|
) -> PangeaResponse[TextGuardResult[None]]:
|
166
349
|
"""
|
@@ -180,7 +363,6 @@ class AIGuard(ServiceBase):
|
|
180
363
|
are to be applied to the text, such as defang malicious URLs.
|
181
364
|
debug: Setting this value to true will provide a detailed analysis
|
182
365
|
of the text data
|
183
|
-
llm_info: Short string hint for the LLM Provider information
|
184
366
|
log_field: Additional fields to include in activity log
|
185
367
|
|
186
368
|
Examples:
|
@@ -194,7 +376,7 @@ class AIGuard(ServiceBase):
|
|
194
376
|
messages: _T,
|
195
377
|
recipe: str | None = None,
|
196
378
|
debug: bool | None = None,
|
197
|
-
|
379
|
+
overrides: Overrides | None = None,
|
198
380
|
log_fields: LogFields | None = None,
|
199
381
|
) -> PangeaResponse[TextGuardResult[_T]]:
|
200
382
|
"""
|
@@ -215,59 +397,20 @@ class AIGuard(ServiceBase):
|
|
215
397
|
are to be applied to the text, such as defang malicious URLs.
|
216
398
|
debug: Setting this value to true will provide a detailed analysis
|
217
399
|
of the text data
|
218
|
-
llm_info: Short string hint for the LLM Provider information
|
219
400
|
log_field: Additional fields to include in activity log
|
220
401
|
|
221
402
|
Examples:
|
222
403
|
response = ai_guard.guard_text(messages=[{"role": "user", "content": "hello world"}])
|
223
404
|
"""
|
224
405
|
|
225
|
-
@overload
|
226
|
-
def guard_text(
|
227
|
-
self,
|
228
|
-
*,
|
229
|
-
llm_input: _T,
|
230
|
-
recipe: str | None = None,
|
231
|
-
debug: bool | None = None,
|
232
|
-
llm_info: str | None = None,
|
233
|
-
log_fields: LogFields | None = None,
|
234
|
-
) -> PangeaResponse[TextGuardResult[_T]]:
|
235
|
-
"""
|
236
|
-
Text Guard for scanning LLM inputs and outputs
|
237
|
-
|
238
|
-
Analyze and redact text to avoid manipulation of the model, addition of
|
239
|
-
malicious content, and other undesirable data transfers.
|
240
|
-
|
241
|
-
OperationId: ai_guard_post_v1_text_guard
|
242
|
-
|
243
|
-
Args:
|
244
|
-
llm_input: Structured full llm payload data to be scanned by AI
|
245
|
-
Guard for PII, sensitive data, malicious content, and other data
|
246
|
-
types defined by the configuration. Supports processing up to
|
247
|
-
10KB of JSON text
|
248
|
-
recipe: Recipe key of a configuration of data types and settings
|
249
|
-
defined in the Pangea User Console. It specifies the rules that
|
250
|
-
are to be applied to the text, such as defang malicious URLs.
|
251
|
-
debug: Setting this value to true will provide a detailed analysis
|
252
|
-
of the text data
|
253
|
-
llm_info: Short string hint for the LLM Provider information
|
254
|
-
log_field: Additional fields to include in activity log
|
255
|
-
|
256
|
-
Examples:
|
257
|
-
response = ai_guard.guard_text(
|
258
|
-
llm_input={"model": "gpt-4o", "messages": [{"role": "user", "content": "hello world"}]}
|
259
|
-
)
|
260
|
-
"""
|
261
|
-
|
262
406
|
def guard_text( # type: ignore[misc]
|
263
407
|
self,
|
264
408
|
text: str | None = None,
|
265
409
|
*,
|
266
410
|
messages: _T | None = None,
|
267
|
-
llm_input: _T | None = None,
|
268
411
|
recipe: str | None = None,
|
269
412
|
debug: bool | None = None,
|
270
|
-
|
413
|
+
overrides: Overrides | None = None,
|
271
414
|
log_fields: LogFields | None = None,
|
272
415
|
) -> PangeaResponse[TextGuardResult[None]]:
|
273
416
|
"""
|
@@ -286,27 +429,19 @@ class AIGuard(ServiceBase):
|
|
286
429
|
PII, sensitive data, malicious content, and other data types
|
287
430
|
defined by the configuration. Supports processing up to 10KB of
|
288
431
|
JSON text
|
289
|
-
llm_input: Structured full llm payload data to be scanned by AI
|
290
|
-
Guard for PII, sensitive data, malicious content, and other data
|
291
|
-
types defined by the configuration. Supports processing up to
|
292
|
-
10KB of JSON text
|
293
432
|
recipe: Recipe key of a configuration of data types and settings
|
294
433
|
defined in the Pangea User Console. It specifies the rules that
|
295
434
|
are to be applied to the text, such as defang malicious URLs.
|
296
435
|
debug: Setting this value to true will provide a detailed analysis
|
297
436
|
of the text data
|
298
|
-
llm_info: Short string hint for the LLM Provider information
|
299
437
|
log_field: Additional fields to include in activity log
|
300
438
|
|
301
439
|
Examples:
|
302
440
|
response = ai_guard.guard_text("text")
|
303
441
|
"""
|
304
442
|
|
305
|
-
if not
|
306
|
-
raise ValueError("
|
307
|
-
|
308
|
-
if sum((text is not None, messages is not None, llm_input is not None)) > 1:
|
309
|
-
raise ValueError("Only one of `text`, `messages`, or `llm_input` can be given at once")
|
443
|
+
if text is not None and messages is not None:
|
444
|
+
raise ValueError("Exactly one of `text` or `messages` must be given")
|
310
445
|
|
311
446
|
return self.request.post(
|
312
447
|
"v1/text/guard",
|
@@ -314,10 +449,9 @@ class AIGuard(ServiceBase):
|
|
314
449
|
data={
|
315
450
|
"text": text,
|
316
451
|
"messages": messages,
|
317
|
-
"llm_input": llm_input,
|
318
452
|
"recipe": recipe,
|
319
453
|
"debug": debug,
|
320
|
-
"
|
454
|
+
"overrides": overrides,
|
321
455
|
"log_fields": log_fields,
|
322
456
|
},
|
323
457
|
)
|
pangea/services/audit/audit.py
CHANGED
@@ -408,10 +408,6 @@ class Audit(ServiceBase, AuditBase):
|
|
408
408
|
config = PangeaConfig(domain="pangea_domain")
|
409
409
|
audit = Audit(token="pangea_token", config=config)
|
410
410
|
"""
|
411
|
-
# FIXME: Temporary check to deprecate config_id from PangeaConfig.
|
412
|
-
# Delete it when deprecate PangeaConfig.config_id
|
413
|
-
if config_id and config is not None and config.config_id is not None:
|
414
|
-
config_id = config.config_id
|
415
411
|
ServiceBase.__init__(self, token, config=config, logger_name=logger_name, config_id=config_id)
|
416
412
|
AuditBase.__init__(
|
417
413
|
self, private_key_file=private_key_file, public_key_info=public_key_info, tenant_id=tenant_id
|
pangea/services/prompt_guard.py
CHANGED
@@ -36,8 +36,8 @@ class GuardResult(PangeaResponseResult):
|
|
36
36
|
analyzer: Optional[str] = None
|
37
37
|
"""Prompt Analyzers for identifying and rejecting properties of prompts"""
|
38
38
|
|
39
|
-
confidence:
|
40
|
-
"""Percent of confidence in the detection result, ranging from 0 to
|
39
|
+
confidence: float
|
40
|
+
"""Percent of confidence in the detection result, ranging from 0 to 1"""
|
41
41
|
|
42
42
|
info: Optional[str] = None
|
43
43
|
"""Extra information about the detection result"""
|
pangea/services/redact.py
CHANGED
@@ -155,12 +155,19 @@ class StructuredRequest(APIRequestModel):
|
|
155
155
|
class StructuredResult(PangeaResponseResult):
|
156
156
|
"""
|
157
157
|
Result class after a structured redact request
|
158
|
-
|
159
158
|
"""
|
160
159
|
|
161
160
|
redacted_data: Optional[Union[Dict, str]] = None
|
161
|
+
"""Redacted data result"""
|
162
|
+
|
162
163
|
count: int
|
164
|
+
"""Number of redactions present in the text"""
|
165
|
+
|
163
166
|
report: Optional[DebugReport] = None
|
167
|
+
"""Describes the decision process for redactions"""
|
168
|
+
|
169
|
+
fpe_context: Optional[str] = None
|
170
|
+
"""FPE context used to encrypt and redact data"""
|
164
171
|
|
165
172
|
|
166
173
|
class UnredactRequest(APIRequestModel):
|
@@ -170,7 +177,6 @@ class UnredactRequest(APIRequestModel):
|
|
170
177
|
Arguments:
|
171
178
|
redacted_data: Data to unredact
|
172
179
|
fpe_context (base64): FPE context used to decrypt and unredact data
|
173
|
-
|
174
180
|
"""
|
175
181
|
|
176
182
|
redacted_data: RedactedData
|
@@ -183,7 +189,6 @@ RedactedData = Union[str, Dict]
|
|
183
189
|
class UnredactResult(PangeaResponseResult):
|
184
190
|
"""
|
185
191
|
Result class after an unredact request
|
186
|
-
|
187
192
|
"""
|
188
193
|
|
189
194
|
data: RedactedData
|
pangea/tools.py
CHANGED
@@ -151,20 +151,17 @@ def get_config_id(environment: TestEnvironment, service: str, config_number: int
|
|
151
151
|
|
152
152
|
def get_custom_schema_test_token(environment: TestEnvironment):
|
153
153
|
env_var_name = f"PANGEA_INTEGRATION_CUSTOM_SCHEMA_TOKEN_{environment}"
|
154
|
-
|
155
|
-
if not value:
|
156
|
-
raise PangeaException(f"{env_var_name} env var need to be set")
|
157
|
-
|
158
|
-
return value
|
154
|
+
return _load_env_var(env_var_name)
|
159
155
|
|
160
156
|
|
161
157
|
def get_custom_schema_vault_test_token(environment: TestEnvironment):
|
162
158
|
env_var_name = f"PANGEA_INTEGRATION_CUSTOM_SCHEMA_TOKEN_{environment}"
|
163
|
-
|
164
|
-
if not value:
|
165
|
-
raise PangeaException(f"{env_var_name} env var need to be set")
|
159
|
+
return _load_env_var(env_var_name)
|
166
160
|
|
167
|
-
|
161
|
+
|
162
|
+
def get_vault_fpe_key_id(environment: TestEnvironment):
|
163
|
+
env_var_name = f"PANGEA_INTEGRATION_FPE_KEY_ID_{environment}"
|
164
|
+
return _load_env_var(env_var_name)
|
168
165
|
|
169
166
|
|
170
167
|
class SequenceFollower:
|
@@ -1,23 +1,24 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: pangea-sdk
|
3
|
-
Version:
|
3
|
+
Version: 6.0.0
|
4
4
|
Summary: Pangea API SDK
|
5
5
|
License: MIT
|
6
6
|
Keywords: Pangea,SDK,Audit
|
7
7
|
Author: Glenn Gallien
|
8
8
|
Author-email: glenn.gallien@pangea.cloud
|
9
|
-
Requires-Python: >=3.9,<4.0.0
|
9
|
+
Requires-Python: >=3.9.2,<4.0.0
|
10
10
|
Classifier: Topic :: Software Development
|
11
11
|
Classifier: Topic :: Software Development :: Libraries
|
12
|
-
Requires-Dist: aiohttp (>=3.11.
|
13
|
-
Requires-Dist: cryptography (>=
|
12
|
+
Requires-Dist: aiohttp (>=3.11.16,<4.0.0)
|
13
|
+
Requires-Dist: cryptography (>=44.0.2,<44.0.3)
|
14
14
|
Requires-Dist: deprecated (>=1.2.18,<2.0.0)
|
15
|
-
Requires-Dist: google-crc32c (>=1.
|
16
|
-
Requires-Dist: pydantic (>=2.
|
15
|
+
Requires-Dist: google-crc32c (>=1.7.1,<2.0.0)
|
16
|
+
Requires-Dist: pydantic (>=2.11.3,<3.0.0)
|
17
17
|
Requires-Dist: python-dateutil (>=2.9.0.post0,<3.0.0)
|
18
18
|
Requires-Dist: requests (>=2.32.3,<3.0.0)
|
19
19
|
Requires-Dist: requests-toolbelt (>=1.0.0,<2.0.0)
|
20
|
-
Requires-Dist: typing-extensions (>=4.
|
20
|
+
Requires-Dist: typing-extensions (>=4.13.2,<5.0.0)
|
21
|
+
Requires-Dist: yarl (>=1.20.0,<2.0.0)
|
21
22
|
Description-Content-Type: text/markdown
|
22
23
|
|
23
24
|
<a href="https://pangea.cloud?utm_source=github&utm_medium=python-sdk" target="_blank" rel="noopener noreferrer">
|
@@ -26,12 +27,11 @@ Description-Content-Type: text/markdown
|
|
26
27
|
|
27
28
|
<br />
|
28
29
|
|
29
|
-
[][Discourse]
|
30
|
+
[][Documentation]
|
31
31
|
|
32
32
|
# Pangea Python SDK
|
33
33
|
|
34
|
-
A Python SDK for integrating with Pangea services. Supports Python v3.9 and
|
34
|
+
A Python SDK for integrating with Pangea services. Supports Python v3.9.2 and
|
35
35
|
above.
|
36
36
|
|
37
37
|
## Installation
|
@@ -63,13 +63,13 @@ the same compatibility guarantees as stable releases.
|
|
63
63
|
Via pip:
|
64
64
|
|
65
65
|
```bash
|
66
|
-
$ pip3 install pangea-sdk==5.5.
|
66
|
+
$ pip3 install pangea-sdk==5.5.0b2
|
67
67
|
```
|
68
68
|
|
69
69
|
Via poetry:
|
70
70
|
|
71
71
|
```bash
|
72
|
-
$ poetry add pangea-sdk==5.5.
|
72
|
+
$ poetry add pangea-sdk==5.5.0b2
|
73
73
|
```
|
74
74
|
|
75
75
|
## Usage
|
@@ -223,6 +223,5 @@ It accepts multiple file formats:
|
|
223
223
|
[GA Examples]: https://github.com/pangeacyber/pangea-python/tree/main/examples
|
224
224
|
[Beta Examples]: https://github.com/pangeacyber/pangea-python/tree/beta/examples
|
225
225
|
[Pangea Console]: https://console.pangea.cloud/
|
226
|
-
[Discourse]: https://l.pangea.cloud/Jd4wlGs
|
227
226
|
[Secure Audit Log]: https://pangea.cloud/docs/audit
|
228
227
|
|
@@ -1,10 +1,10 @@
|
|
1
|
-
pangea/__init__.py,sha256=
|
1
|
+
pangea/__init__.py,sha256=WlZa15dkqzwfQrtPRyiGS0sYP9wBJcaBvWFl_kcNUjs,246
|
2
2
|
pangea/asyncio/__init__.py,sha256=kjEMkqMQ521LlMSu5jn3_WgweyArwVZ2C-s3x7mR6Pk,45
|
3
3
|
pangea/asyncio/file_uploader.py,sha256=wI7epib7Rc5jtZw4eJ1L1SlmutDG6CPv59C8N2UPhtY,1436
|
4
4
|
pangea/asyncio/request.py,sha256=lpLY-o405r3-VUfrAE5uxYxI8UjM4hjPqUzAUtOGE5o,18040
|
5
5
|
pangea/asyncio/services/__init__.py,sha256=L6Tdhjfx_ZECHskhLMPaCcOefi-r-imw6q_zlU4j-FY,464
|
6
|
-
pangea/asyncio/services/ai_guard.py,sha256=
|
7
|
-
pangea/asyncio/services/audit.py,sha256=
|
6
|
+
pangea/asyncio/services/ai_guard.py,sha256=rFksT8LQkyioW3QOq4fLCEZbW5SXiYWpWjLbVovRouE,6294
|
7
|
+
pangea/asyncio/services/audit.py,sha256=Ue3KDmTn-a2KsqlzxbakLQJAWiRyLaJrYVi1hO7a6sw,26030
|
8
8
|
pangea/asyncio/services/authn.py,sha256=rPeLJweL8mYH_t4ebcQn4n_Wglr3kClKNnCXNCimZU4,46622
|
9
9
|
pangea/asyncio/services/authz.py,sha256=B_0_nhDMJcjNpjpCx3Vi2LDRhlmfV9325GKbUZ8reos,10025
|
10
10
|
pangea/asyncio/services/base.py,sha256=vRFVcO_uEAGJte3OUUBLD43RoiiFB1vC7SPyN6yEMoA,3158
|
@@ -17,7 +17,7 @@ pangea/asyncio/services/sanitize.py,sha256=EbSdq_v9yZWce9xEYWvZharE9bJcxw8cg5Pv8
|
|
17
17
|
pangea/asyncio/services/share.py,sha256=Qd2Oh4UsLwu7Zo4Xy1KABHuP4TJ9AtcN-XzldvilFVo,30773
|
18
18
|
pangea/asyncio/services/vault.py,sha256=VqrJGSEdq6MlZRI6cJpkthhIsqLClSQdgVxwYCbIwEk,77079
|
19
19
|
pangea/audit_logger.py,sha256=gRkCfUUT5LDNaycwxkhZUySgY47jDfn1ZeKOul4XCQI,3842
|
20
|
-
pangea/config.py,sha256=
|
20
|
+
pangea/config.py,sha256=Z2WT_UG0qBQzzVzBfloXYFxS21mSg1YXQ36cAVCqrJk,1963
|
21
21
|
pangea/crypto/rsa.py,sha256=mwSiNy571KAGr3F6oEM0CXWkl9D023ch8ldbZZeLj_4,4747
|
22
22
|
pangea/deep_verify.py,sha256=ZGraaL7TCxwRBIDqjBFR0clKlhAC-Yce6kD-1LClhG8,8616
|
23
23
|
pangea/deprecated.py,sha256=IjFYEVvY1E0ld0SMkEYC1o62MAleX3nnT1If2dFVbHo,608
|
@@ -25,11 +25,11 @@ pangea/dump_audit.py,sha256=IevqaUUh7GDepdIW7slSxeZbkPrWIVbcX3sr4DgpJXI,7090
|
|
25
25
|
pangea/exceptions.py,sha256=OBtzUECpNa6vNp8ySkHC-tm4QjFRCOAHBkMHqzAlOu8,5656
|
26
26
|
pangea/file_uploader.py,sha256=4RQ44xt-faApC61nn2PlwHT7XYrJ4GeQA8Ug4tySEAg,1227
|
27
27
|
pangea/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
28
|
-
pangea/request.py,sha256=
|
28
|
+
pangea/request.py,sha256=4ZVD1F3CS4XdLM45vfhlCazZ5NQF1jUzu4j31yjH3KE,24689
|
29
29
|
pangea/response.py,sha256=lPAcYsF9Xg166CiyhCofVmQA-W4jevh0MQXxUa8Re68,7737
|
30
30
|
pangea/services/__init__.py,sha256=h36HzyIGaI5kO6l3UCwKHx_Kd-m_9mYVwn5MLRVzblI,408
|
31
|
-
pangea/services/ai_guard.py,sha256=
|
32
|
-
pangea/services/audit/audit.py,sha256=
|
31
|
+
pangea/services/ai_guard.py,sha256=X1DR1JTYZnLqBFFAHgmRk4xqyGF3GQMO1B3_cqLLVfU,15774
|
32
|
+
pangea/services/audit/audit.py,sha256=TbDiO5eAHWCWAynQ4PChonTEN7z7ehZaR-duxbIFZ6Q,39068
|
33
33
|
pangea/services/audit/exceptions.py,sha256=bhVuYe4ammacOVxwg98CChxvwZf5FKgR2DcgqILOcwc,471
|
34
34
|
pangea/services/audit/models.py,sha256=1h1B9eSYQMYG3f8WNi1UcDX2-impRrET_ErjJYUnj7M,14678
|
35
35
|
pangea/services/audit/signing.py,sha256=5A4hvPtpfP2kMz8bsiiKUACriXbh5dv9gb_rbqiUtuI,5583
|
@@ -41,8 +41,8 @@ pangea/services/base.py,sha256=43pWQcR9CeT4sGzgctF3Sy4M_h7DaUzkuZD2Z7CcDUU,3845
|
|
41
41
|
pangea/services/embargo.py,sha256=9Wfku4td5ORaIENKmnGmS5jxJJIRfWp6Q51L36Jsy0I,3897
|
42
42
|
pangea/services/file_scan.py,sha256=QiO80uKqB_BnAOiYQKznXfxpa5j40qqETE3-zBRT_QE,7813
|
43
43
|
pangea/services/intel.py,sha256=y1EX2ctYIxQc52lmHp6-Q_UIDM--t3fOpXDssWiRPfo,56474
|
44
|
-
pangea/services/prompt_guard.py,sha256=
|
45
|
-
pangea/services/redact.py,sha256=
|
44
|
+
pangea/services/prompt_guard.py,sha256=Cq8ume2_YPfHre4iN6FYkyTV7NrdwLXlr_wnilfKotE,3446
|
45
|
+
pangea/services/redact.py,sha256=ZTZgx3w4X923ZjWcBpI4c0gVh9cpJpcUpWuTNVVuHeY,13143
|
46
46
|
pangea/services/sanitize.py,sha256=eAN1HhObiKqygy6HHcfl0NmxYfPMvqSKepwEAVVIIEE,12936
|
47
47
|
pangea/services/share/file_format.py,sha256=1svO1ee_aenA9zoO_AaU-Rk5Ulp7kcPOc_KwNoluyQE,2797
|
48
48
|
pangea/services/share/share.py,sha256=hlhkIr6ScJ5oMFUs9no4HtHNoUEbYU4KoLkiGLxex30,52343
|
@@ -52,9 +52,9 @@ pangea/services/vault/models/keys.py,sha256=duAuTiOby_D7MloRvN4gNj0P-b-jx9sdtplA
|
|
52
52
|
pangea/services/vault/models/secret.py,sha256=ItGdkulM-SEySfcm4a5yGxMvo_omjC7kChv6gdbFnn8,1142
|
53
53
|
pangea/services/vault/models/symmetric.py,sha256=t8xCM1wGGKDBpOqTggFueO4-4-2IFmyxqcs7_PDr7U0,2562
|
54
54
|
pangea/services/vault/vault.py,sha256=ow-Zm7PYzfWIfUcA4UNnpeL2DHfZM4C7inRDmNR3zQU,76196
|
55
|
-
pangea/tools.py,sha256=
|
55
|
+
pangea/tools.py,sha256=icHduOfZLi02UYdGb5Xl1fQqu-PBRB4tiDPT_nL2Q8E,6380
|
56
56
|
pangea/utils.py,sha256=dZ6MwFVEWXUgXvvDg-k6JnvVfsgslvtaBd7ez7afrqk,4983
|
57
57
|
pangea/verify_audit.py,sha256=nSP17OzoSPdvezRExwfcf45H8ZPZnxZu-CbEp3qFJO0,17354
|
58
|
-
pangea_sdk-
|
59
|
-
pangea_sdk-
|
60
|
-
pangea_sdk-
|
58
|
+
pangea_sdk-6.0.0.dist-info/METADATA,sha256=X9QYxYoEw53LK2rdWTOvEs9I24--d27P7Xeft4DTGzM,6886
|
59
|
+
pangea_sdk-6.0.0.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
|
60
|
+
pangea_sdk-6.0.0.dist-info/RECORD,,
|