pangea-sdk 6.3.0__tar.gz → 6.5.0b1__tar.gz
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_sdk-6.3.0 → pangea_sdk-6.5.0b1}/PKG-INFO +1 -1
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/__init__.py +1 -1
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/asyncio/request.py +152 -19
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/asyncio/services/__init__.py +1 -0
- pangea_sdk-6.5.0b1/pangea/asyncio/services/ai_guard.py +342 -0
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/asyncio/services/audit.py +301 -1
- pangea_sdk-6.5.0b1/pangea/asyncio/services/management.py +576 -0
- pangea_sdk-6.5.0b1/pangea/asyncio/services/prompt_guard.py +194 -0
- pangea_sdk-6.5.0b1/pangea/asyncio/services/redact.py +467 -0
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/request.py +154 -19
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/services/__init__.py +1 -0
- pangea_sdk-6.5.0b1/pangea/services/ai_guard.py +1180 -0
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/services/audit/audit.py +301 -1
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/services/audit/models.py +273 -1
- pangea_sdk-6.5.0b1/pangea/services/management.py +720 -0
- pangea_sdk-6.5.0b1/pangea/services/prompt_guard.py +309 -0
- pangea_sdk-6.5.0b1/pangea/services/redact.py +854 -0
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pyproject.toml +3 -3
- pangea_sdk-6.3.0/pangea/asyncio/services/ai_guard.py +0 -169
- pangea_sdk-6.3.0/pangea/asyncio/services/prompt_guard.py +0 -84
- pangea_sdk-6.3.0/pangea/asyncio/services/redact.py +0 -206
- pangea_sdk-6.3.0/pangea/services/ai_guard.py +0 -468
- pangea_sdk-6.3.0/pangea/services/prompt_guard.py +0 -118
- pangea_sdk-6.3.0/pangea/services/redact.py +0 -388
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/README.md +0 -0
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/asyncio/__init__.py +0 -0
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/asyncio/file_uploader.py +0 -0
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/asyncio/services/authn.py +0 -0
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/asyncio/services/authz.py +0 -0
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/asyncio/services/base.py +0 -0
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/asyncio/services/embargo.py +0 -0
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/asyncio/services/file_scan.py +0 -0
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/asyncio/services/intel.py +0 -0
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/asyncio/services/sanitize.py +0 -0
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/asyncio/services/share.py +0 -0
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/asyncio/services/vault.py +0 -0
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/audit_logger.py +0 -0
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/config.py +0 -0
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/crypto/rsa.py +0 -0
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/deep_verify.py +0 -0
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/deprecated.py +0 -0
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/dump_audit.py +0 -0
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/exceptions.py +0 -0
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/file_uploader.py +0 -0
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/py.typed +0 -0
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/response.py +0 -0
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/services/audit/exceptions.py +0 -0
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/services/audit/signing.py +0 -0
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/services/audit/util.py +0 -0
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/services/authn/authn.py +0 -0
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/services/authn/models.py +0 -0
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/services/authz.py +0 -0
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/services/base.py +0 -0
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/services/embargo.py +0 -0
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/services/file_scan.py +0 -0
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/services/intel.py +0 -0
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/services/sanitize.py +0 -0
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/services/share/file_format.py +0 -0
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/services/share/share.py +0 -0
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/services/vault/models/asymmetric.py +0 -0
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/services/vault/models/common.py +0 -0
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/services/vault/models/keys.py +0 -0
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/services/vault/models/secret.py +0 -0
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/services/vault/models/symmetric.py +0 -0
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/services/vault/vault.py +0 -0
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/tools.py +0 -0
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/utils.py +0 -0
- {pangea_sdk-6.3.0 → pangea_sdk-6.5.0b1}/pangea/verify_audit.py +0 -0
@@ -10,13 +10,13 @@ import asyncio
|
|
10
10
|
import json
|
11
11
|
import time
|
12
12
|
from collections.abc import Iterable, Mapping
|
13
|
-
from typing import Dict, List, Optional, Sequence, Tuple, Type, Union, cast
|
13
|
+
from typing import Dict, List, Optional, Sequence, Tuple, Type, Union, cast, overload
|
14
14
|
|
15
15
|
import aiohttp
|
16
16
|
from aiohttp import FormData
|
17
|
-
from pydantic import BaseModel
|
17
|
+
from pydantic import BaseModel, TypeAdapter
|
18
18
|
from pydantic_core import to_jsonable_python
|
19
|
-
from typing_extensions import Any, TypeAlias, TypeVar, override
|
19
|
+
from typing_extensions import Any, Literal, TypeAlias, TypeVar, override
|
20
20
|
|
21
21
|
import pangea.exceptions as pe
|
22
22
|
from pangea.request import MultipartResponse, PangeaRequestBase
|
@@ -50,6 +50,24 @@ class PangeaRequestAsync(PangeaRequestBase):
|
|
50
50
|
be set in PangeaConfig.
|
51
51
|
"""
|
52
52
|
|
53
|
+
async def delete(self, endpoint: str) -> None:
|
54
|
+
"""
|
55
|
+
Makes a DELETE call to a Pangea endpoint.
|
56
|
+
|
57
|
+
Args:
|
58
|
+
endpoint: The Pangea API endpoint.
|
59
|
+
"""
|
60
|
+
|
61
|
+
url = self._url(endpoint)
|
62
|
+
|
63
|
+
self.logger.debug(
|
64
|
+
json.dumps({"service": self.service, "action": "delete", "url": url}, default=default_encoder)
|
65
|
+
)
|
66
|
+
|
67
|
+
requests_response = await self._http_delete(url, headers=self._headers())
|
68
|
+
await self._check_http_errors(requests_response)
|
69
|
+
|
70
|
+
@overload
|
53
71
|
async def post(
|
54
72
|
self,
|
55
73
|
endpoint: str,
|
@@ -58,18 +76,60 @@ class PangeaRequestAsync(PangeaRequestBase):
|
|
58
76
|
files: Optional[List[Tuple]] = None,
|
59
77
|
poll_result: bool = True,
|
60
78
|
url: Optional[str] = None,
|
79
|
+
*,
|
80
|
+
pangea_response: Literal[True] = True,
|
61
81
|
) -> PangeaResponse[TResult]:
|
62
|
-
"""
|
82
|
+
"""
|
83
|
+
Makes a POST call to a Pangea Service endpoint.
|
63
84
|
|
64
85
|
Args:
|
65
|
-
endpoint
|
66
|
-
data
|
86
|
+
endpoint: The Pangea Service API endpoint.
|
87
|
+
data: The POST body payload object
|
67
88
|
|
68
89
|
Returns:
|
69
90
|
PangeaResponse which contains the response in its entirety and
|
70
91
|
various properties to retrieve individual fields
|
71
92
|
"""
|
72
93
|
|
94
|
+
@overload
|
95
|
+
async def post(
|
96
|
+
self,
|
97
|
+
endpoint: str,
|
98
|
+
result_class: Type[TResult],
|
99
|
+
data: str | BaseModel | Mapping[str, Any] | None = None,
|
100
|
+
files: Optional[List[Tuple]] = None,
|
101
|
+
poll_result: bool = True,
|
102
|
+
url: Optional[str] = None,
|
103
|
+
*,
|
104
|
+
pangea_response: Literal[False],
|
105
|
+
) -> TResult:
|
106
|
+
"""
|
107
|
+
Makes a POST call to a Pangea Service endpoint.
|
108
|
+
|
109
|
+
Args:
|
110
|
+
endpoint: The Pangea Service API endpoint.
|
111
|
+
data: The POST body payload object
|
112
|
+
"""
|
113
|
+
|
114
|
+
async def post(
|
115
|
+
self,
|
116
|
+
endpoint: str,
|
117
|
+
result_class: Type[TResult],
|
118
|
+
data: str | BaseModel | Mapping[str, Any] | None = None,
|
119
|
+
files: Optional[List[Tuple]] = None,
|
120
|
+
poll_result: bool = True,
|
121
|
+
url: Optional[str] = None,
|
122
|
+
*,
|
123
|
+
pangea_response: bool = True,
|
124
|
+
) -> PangeaResponse[TResult] | TResult:
|
125
|
+
"""
|
126
|
+
Makes a POST call to a Pangea Service endpoint.
|
127
|
+
|
128
|
+
Args:
|
129
|
+
endpoint: The Pangea Service API endpoint.
|
130
|
+
data: The POST body payload object
|
131
|
+
"""
|
132
|
+
|
73
133
|
if isinstance(data, BaseModel):
|
74
134
|
data = data.model_dump(exclude_none=True)
|
75
135
|
|
@@ -109,9 +169,13 @@ class PangeaRequestAsync(PangeaRequestBase):
|
|
109
169
|
|
110
170
|
await self._check_http_errors(requests_response)
|
111
171
|
|
172
|
+
if not pangea_response:
|
173
|
+
type_adapter = TypeAdapter(result_class)
|
174
|
+
return type_adapter.validate_python(await requests_response.json())
|
175
|
+
|
112
176
|
if "multipart/form-data" in requests_response.headers.get("content-type", ""):
|
113
177
|
multipart_response = await self._process_multipart_response(requests_response)
|
114
|
-
|
178
|
+
pangea_response_obj: PangeaResponse = PangeaResponse(
|
115
179
|
requests_response,
|
116
180
|
result_class=result_class,
|
117
181
|
json=multipart_response.pangea_json,
|
@@ -124,49 +188,110 @@ class PangeaRequestAsync(PangeaRequestBase):
|
|
124
188
|
json.dumps({"service": self.service, "action": "post", "url": url, "response": json_resp})
|
125
189
|
)
|
126
190
|
|
127
|
-
|
191
|
+
pangea_response_obj = PangeaResponse(requests_response, result_class=result_class, json=json_resp)
|
128
192
|
except aiohttp.ContentTypeError as e:
|
129
193
|
raise pe.PangeaException(
|
130
194
|
f"Failed to decode json response. {e}. Body: {await requests_response.text()}"
|
131
195
|
) from e
|
132
196
|
|
133
197
|
if poll_result:
|
134
|
-
|
198
|
+
pangea_response_obj = await self._handle_queued_result(pangea_response_obj)
|
135
199
|
|
136
|
-
return self._check_response(
|
200
|
+
return self._check_response(pangea_response_obj)
|
137
201
|
|
138
|
-
|
139
|
-
|
202
|
+
@overload
|
203
|
+
async def get(
|
204
|
+
self,
|
205
|
+
path: str,
|
206
|
+
result_class: Type[TResult],
|
207
|
+
check_response: bool = True,
|
208
|
+
*,
|
209
|
+
params: (
|
210
|
+
Mapping[str | bytes | int | float, str | bytes | int | float | Iterable[str | bytes | int | float] | None]
|
211
|
+
| None
|
212
|
+
) = None,
|
213
|
+
pangea_response: Literal[True] = True,
|
214
|
+
) -> PangeaResponse[TResult]:
|
215
|
+
"""
|
216
|
+
Makes the GET call to a Pangea Service endpoint.
|
140
217
|
|
141
218
|
Args:
|
142
|
-
|
143
|
-
|
219
|
+
path: Additional URL path
|
220
|
+
params: Dictionary of querystring data to attach to the request
|
144
221
|
|
145
222
|
Returns:
|
146
223
|
PangeaResponse which contains the response in its entirety and
|
147
224
|
various properties to retrieve individual fields
|
148
225
|
"""
|
149
226
|
|
227
|
+
@overload
|
228
|
+
async def get(
|
229
|
+
self,
|
230
|
+
path: str,
|
231
|
+
result_class: Type[TResult],
|
232
|
+
check_response: bool = True,
|
233
|
+
*,
|
234
|
+
params: (
|
235
|
+
Mapping[str | bytes | int | float, str | bytes | int | float | Iterable[str | bytes | int | float] | None]
|
236
|
+
| None
|
237
|
+
) = None,
|
238
|
+
pangea_response: Literal[False] = False,
|
239
|
+
) -> TResult:
|
240
|
+
"""
|
241
|
+
Makes the GET call to a Pangea Service endpoint.
|
242
|
+
|
243
|
+
Args:
|
244
|
+
path: Additional URL path
|
245
|
+
params: Dictionary of querystring data to attach to the request
|
246
|
+
"""
|
247
|
+
|
248
|
+
async def get(
|
249
|
+
self,
|
250
|
+
path: str,
|
251
|
+
result_class: Type[TResult],
|
252
|
+
check_response: bool = True,
|
253
|
+
*,
|
254
|
+
params: (
|
255
|
+
Mapping[str | bytes | int | float, str | bytes | int | float | Iterable[str | bytes | int | float] | None]
|
256
|
+
| None
|
257
|
+
) = None,
|
258
|
+
pangea_response: bool = True,
|
259
|
+
) -> PangeaResponse[TResult] | TResult:
|
260
|
+
"""
|
261
|
+
Makes the GET call to a Pangea Service endpoint.
|
262
|
+
|
263
|
+
Args:
|
264
|
+
path: Additional URL path
|
265
|
+
params: Dictionary of querystring data to attach to the request
|
266
|
+
pangea_response: Whether or not the response body follows Pangea's
|
267
|
+
standard response schema
|
268
|
+
"""
|
269
|
+
|
150
270
|
url = self._url(path)
|
151
271
|
self.logger.debug(json.dumps({"service": self.service, "action": "get", "url": url}))
|
152
272
|
|
153
|
-
async with self.session.get(url, headers=self._headers()) as requests_response:
|
273
|
+
async with self.session.get(url, params=params, headers=self._headers()) as requests_response:
|
154
274
|
await self._check_http_errors(requests_response)
|
155
|
-
|
275
|
+
|
276
|
+
if not pangea_response:
|
277
|
+
type_adapter = TypeAdapter(result_class)
|
278
|
+
return type_adapter.validate_python(await requests_response.json())
|
279
|
+
|
280
|
+
pangea_response_obj = PangeaResponse(
|
156
281
|
requests_response, result_class=result_class, json=await requests_response.json()
|
157
282
|
)
|
158
283
|
|
159
284
|
self.logger.debug(
|
160
285
|
json.dumps(
|
161
|
-
{"service": self.service, "action": "get", "url": url, "response":
|
286
|
+
{"service": self.service, "action": "get", "url": url, "response": pangea_response_obj.json},
|
162
287
|
default=default_encoder,
|
163
288
|
)
|
164
289
|
)
|
165
290
|
|
166
291
|
if check_response is False:
|
167
|
-
return
|
292
|
+
return pangea_response_obj
|
168
293
|
|
169
|
-
return self._check_response(
|
294
|
+
return self._check_response(pangea_response_obj)
|
170
295
|
|
171
296
|
async def _check_http_errors(self, resp: aiohttp.ClientResponse):
|
172
297
|
if resp.status == 503:
|
@@ -300,6 +425,14 @@ class PangeaRequestAsync(PangeaRequestBase):
|
|
300
425
|
attached_files = await self._get_attached_files(multipart_reader)
|
301
426
|
return MultipartResponse(pangea_json, attached_files) # type: ignore[arg-type]
|
302
427
|
|
428
|
+
async def _http_delete(
|
429
|
+
self,
|
430
|
+
url: str,
|
431
|
+
*,
|
432
|
+
headers: Mapping[str, str | bytes | None] = {},
|
433
|
+
) -> aiohttp.ClientResponse:
|
434
|
+
return await self.session.delete(url, headers=headers)
|
435
|
+
|
303
436
|
async def _http_post(
|
304
437
|
self,
|
305
438
|
url: str,
|
@@ -7,6 +7,7 @@ from .authz import AuthZAsync
|
|
7
7
|
from .embargo import EmbargoAsync
|
8
8
|
from .file_scan import FileScanAsync
|
9
9
|
from .intel import DomainIntelAsync, FileIntelAsync, IpIntelAsync, UrlIntelAsync, UserIntelAsync
|
10
|
+
from .management import ManagementAsync
|
10
11
|
from .prompt_guard import PromptGuardAsync
|
11
12
|
from .redact import RedactAsync
|
12
13
|
from .sanitize import SanitizeAsync
|
@@ -0,0 +1,342 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
|
3
|
+
from collections.abc import Mapping, Sequence
|
4
|
+
from typing import Any, overload
|
5
|
+
|
6
|
+
from typing_extensions import Literal, TypeVar
|
7
|
+
|
8
|
+
from pangea.asyncio.services.base import ServiceBaseAsync
|
9
|
+
from pangea.config import PangeaConfig
|
10
|
+
from pangea.response import PangeaResponse
|
11
|
+
from pangea.services.ai_guard import (
|
12
|
+
AuditDataActivityConfig,
|
13
|
+
ConnectionsConfig,
|
14
|
+
ExtraInfo,
|
15
|
+
GuardResult,
|
16
|
+
LogFields,
|
17
|
+
Message,
|
18
|
+
Overrides,
|
19
|
+
RecipeConfig,
|
20
|
+
ServiceConfig,
|
21
|
+
ServiceConfigFilter,
|
22
|
+
ServiceConfigsPage,
|
23
|
+
TextGuardResult,
|
24
|
+
)
|
25
|
+
|
26
|
+
_T = TypeVar("_T")
|
27
|
+
|
28
|
+
|
29
|
+
class AIGuardAsync(ServiceBaseAsync):
|
30
|
+
"""AI Guard service client.
|
31
|
+
|
32
|
+
Provides methods to interact with Pangea's AI Guard service.
|
33
|
+
|
34
|
+
Examples:
|
35
|
+
from pangea.asyncio.services import AIGuardAsync
|
36
|
+
|
37
|
+
ai_guard = AIGuardAsync(token="pangea_token")
|
38
|
+
"""
|
39
|
+
|
40
|
+
service_name = "ai-guard"
|
41
|
+
|
42
|
+
def __init__(
|
43
|
+
self, token: str, config: PangeaConfig | None = None, logger_name: str = "pangea", config_id: str | None = None
|
44
|
+
) -> None:
|
45
|
+
"""
|
46
|
+
AI Guard service client.
|
47
|
+
|
48
|
+
Initializes a new AI Guard client.
|
49
|
+
|
50
|
+
Args:
|
51
|
+
token: Pangea API token.
|
52
|
+
config: Pangea service configuration.
|
53
|
+
logger_name: Logger name.
|
54
|
+
config_id: Configuration ID.
|
55
|
+
|
56
|
+
Examples:
|
57
|
+
from pangea.asyncio.services import AIGuardAsync
|
58
|
+
|
59
|
+
ai_guard = AIGuardAsync(token="pangea_token")
|
60
|
+
"""
|
61
|
+
|
62
|
+
super().__init__(token, config, logger_name, config_id)
|
63
|
+
|
64
|
+
@overload
|
65
|
+
async def guard_text(
|
66
|
+
self,
|
67
|
+
text: str,
|
68
|
+
*,
|
69
|
+
debug: bool | None = None,
|
70
|
+
log_fields: LogFields | None = None,
|
71
|
+
overrides: Overrides | None = None,
|
72
|
+
recipe: str | None = None,
|
73
|
+
) -> PangeaResponse[TextGuardResult]:
|
74
|
+
"""
|
75
|
+
Guard LLM input and output text
|
76
|
+
|
77
|
+
Detect, remove, or block malicious content and intent in LLM inputs and
|
78
|
+
outputs to prevent model manipulation and data leakage.
|
79
|
+
|
80
|
+
OperationId: ai_guard_post_v1_text_guard
|
81
|
+
|
82
|
+
Args:
|
83
|
+
text: Text to be scanned by AI Guard for PII, sensitive data,
|
84
|
+
malicious content, and other data types defined by the
|
85
|
+
configuration. Supports processing up to 20 KiB of text.
|
86
|
+
debug: Setting this value to true will provide a detailed analysis
|
87
|
+
of the text data
|
88
|
+
log_field: Additional fields to include in activity log
|
89
|
+
overrides: Overrides flags. Note: This parameter has no effect when
|
90
|
+
the request is made by AIDR
|
91
|
+
recipe: Recipe key of a configuration of data types and settings
|
92
|
+
defined in the Pangea User Console. It specifies the rules that
|
93
|
+
are to be applied to the text, such as defang malicious URLs.
|
94
|
+
|
95
|
+
Examples:
|
96
|
+
response = await ai_guard.guard_text("text")
|
97
|
+
"""
|
98
|
+
|
99
|
+
@overload
|
100
|
+
async def guard_text(
|
101
|
+
self,
|
102
|
+
*,
|
103
|
+
messages: Sequence[Message],
|
104
|
+
recipe: str | None = None,
|
105
|
+
debug: bool | None = None,
|
106
|
+
overrides: Overrides | None = None,
|
107
|
+
log_fields: LogFields | None = None,
|
108
|
+
) -> PangeaResponse[TextGuardResult]:
|
109
|
+
"""
|
110
|
+
Guard LLM input and output text
|
111
|
+
|
112
|
+
Detect, remove, or block malicious content and intent in LLM inputs and
|
113
|
+
outputs to prevent model manipulation and data leakage.
|
114
|
+
|
115
|
+
OperationId: ai_guard_post_v1_text_guard
|
116
|
+
|
117
|
+
Args:
|
118
|
+
messages: Structured messages data to be scanned by AI Guard for
|
119
|
+
PII, sensitive data, malicious content, and other data types
|
120
|
+
defined by the configuration. Supports processing up to 20 KiB
|
121
|
+
of JSON text using Pangea message format.
|
122
|
+
debug: Setting this value to true will provide a detailed analysis
|
123
|
+
of the text data
|
124
|
+
log_field: Additional fields to include in activity log
|
125
|
+
overrides: Overrides flags. Note: This parameter has no effect when
|
126
|
+
the request is made by AIDR
|
127
|
+
recipe: Recipe key of a configuration of data types and settings
|
128
|
+
defined in the Pangea User Console. It specifies the rules that
|
129
|
+
are to be applied to the text, such as defang malicious URLs.
|
130
|
+
|
131
|
+
Examples:
|
132
|
+
response = await ai_guard.guard_text(messages=[Message(role="user", content="hello world")])
|
133
|
+
"""
|
134
|
+
|
135
|
+
async def guard_text(
|
136
|
+
self,
|
137
|
+
text: str | None = None,
|
138
|
+
*,
|
139
|
+
messages: Sequence[Message] | None = None,
|
140
|
+
recipe: str | None = None,
|
141
|
+
debug: bool | None = None,
|
142
|
+
overrides: Overrides | None = None,
|
143
|
+
log_fields: LogFields | None = None,
|
144
|
+
) -> PangeaResponse[TextGuardResult]:
|
145
|
+
"""
|
146
|
+
Guard LLM input and output text
|
147
|
+
|
148
|
+
Detect, remove, or block malicious content and intent in LLM inputs and
|
149
|
+
outputs to prevent model manipulation and data leakage.
|
150
|
+
|
151
|
+
OperationId: ai_guard_post_v1_text_guard
|
152
|
+
|
153
|
+
Args:
|
154
|
+
text: Text to be scanned by AI Guard for PII, sensitive data,
|
155
|
+
malicious content, and other data types defined by the
|
156
|
+
configuration. Supports processing up to 10KB of text.
|
157
|
+
messages: Structured messages data to be scanned by AI Guard for
|
158
|
+
PII, sensitive data, malicious content, and other data types
|
159
|
+
defined by the configuration. Supports processing up to 10KB of
|
160
|
+
JSON text
|
161
|
+
debug: Setting this value to true will provide a detailed analysis
|
162
|
+
of the text data
|
163
|
+
log_field: Additional fields to include in activity log
|
164
|
+
overrides: Overrides flags. Note: This parameter has no effect when
|
165
|
+
the request is made by AIDR
|
166
|
+
recipe: Recipe key of a configuration of data types and settings
|
167
|
+
defined in the Pangea User Console. It specifies the rules that
|
168
|
+
are to be applied to the text, such as defang malicious URLs.
|
169
|
+
|
170
|
+
Examples:
|
171
|
+
response = await ai_guard.guard_text("text")
|
172
|
+
"""
|
173
|
+
|
174
|
+
if text is not None and messages is not None:
|
175
|
+
raise ValueError("Exactly one of `text` or `messages` must be given")
|
176
|
+
|
177
|
+
return await self.request.post(
|
178
|
+
"v1/text/guard",
|
179
|
+
TextGuardResult,
|
180
|
+
data={
|
181
|
+
"text": text,
|
182
|
+
"messages": messages,
|
183
|
+
"recipe": recipe,
|
184
|
+
"debug": debug,
|
185
|
+
"overrides": overrides,
|
186
|
+
"log_fields": log_fields,
|
187
|
+
},
|
188
|
+
)
|
189
|
+
|
190
|
+
async def guard(
|
191
|
+
self,
|
192
|
+
input: Mapping[str, Any],
|
193
|
+
*,
|
194
|
+
recipe: str | None = None,
|
195
|
+
debug: bool | None = None,
|
196
|
+
overrides: Overrides | None = None,
|
197
|
+
app_id: str | None = None,
|
198
|
+
actor_id: str | None = None,
|
199
|
+
llm_provider: str | None = None,
|
200
|
+
model: str | None = None,
|
201
|
+
model_version: str | None = None,
|
202
|
+
request_token_count: int | None = None,
|
203
|
+
response_token_count: int | None = None,
|
204
|
+
source_ip: str | None = None,
|
205
|
+
source_location: str | None = None,
|
206
|
+
tenant_id: str | None = None,
|
207
|
+
event_type: Literal["input", "output"] | None = None,
|
208
|
+
sensor_instance_id: str | None = None,
|
209
|
+
extra_info: ExtraInfo | None = None,
|
210
|
+
count_tokens: bool | None = None,
|
211
|
+
) -> PangeaResponse[GuardResult]:
|
212
|
+
"""
|
213
|
+
Guard LLM input and output
|
214
|
+
|
215
|
+
Analyze and redact content to avoid manipulation of the model, addition
|
216
|
+
of malicious content, and other undesirable data transfers.
|
217
|
+
|
218
|
+
OperationId: ai_guard_post_v1beta_guard
|
219
|
+
|
220
|
+
Args:
|
221
|
+
input: 'messages' (required) contains Prompt content and role array
|
222
|
+
in JSON format. The `content` is the multimodal text or image
|
223
|
+
input that will be analyzed. Additional properties such as
|
224
|
+
'tools' may be provided for analysis.
|
225
|
+
recipe: Recipe key of a configuration of data types and settings defined in the Pangea User Console. It specifies the rules that are to be applied to the text, such as defang malicious URLs.
|
226
|
+
debug: Setting this value to true will provide a detailed analysis of the text data
|
227
|
+
app_name: Name of source application.
|
228
|
+
llm_provider: Underlying LLM. Example: 'OpenAI'.
|
229
|
+
model: Model used to perform the event. Example: 'gpt'.
|
230
|
+
model_version: Model version used to perform the event. Example: '3.5'.
|
231
|
+
request_token_count: Number of tokens in the request.
|
232
|
+
response_token_count: Number of tokens in the response.
|
233
|
+
source_ip: IP address of user or app or agent.
|
234
|
+
source_location: Location of user or app or agent.
|
235
|
+
tenant_id: For gateway-like integrations with multi-tenant support.
|
236
|
+
event_type: (AIDR) Event Type.
|
237
|
+
sensor_instance_id: (AIDR) sensor instance id.
|
238
|
+
extra_info: (AIDR) Logging schema.
|
239
|
+
count_tokens: Provide input and output token count.
|
240
|
+
"""
|
241
|
+
return await self.request.post(
|
242
|
+
"v1beta/guard",
|
243
|
+
GuardResult,
|
244
|
+
data={
|
245
|
+
"input": input,
|
246
|
+
"recipe": recipe,
|
247
|
+
"debug": debug,
|
248
|
+
"overrides": overrides,
|
249
|
+
"app_id": app_id,
|
250
|
+
"actor_id": actor_id,
|
251
|
+
"llm_provider": llm_provider,
|
252
|
+
"model": model,
|
253
|
+
"model_version": model_version,
|
254
|
+
"request_token_count": request_token_count,
|
255
|
+
"response_token_count": response_token_count,
|
256
|
+
"source_ip": source_ip,
|
257
|
+
"source_location": source_location,
|
258
|
+
"tenant_id": tenant_id,
|
259
|
+
"event_type": event_type,
|
260
|
+
"sensor_instance_id": sensor_instance_id,
|
261
|
+
"extra_info": extra_info,
|
262
|
+
"count_tokens": count_tokens,
|
263
|
+
},
|
264
|
+
)
|
265
|
+
|
266
|
+
async def get_service_config(self, id: str) -> PangeaResponse[ServiceConfig]:
|
267
|
+
"""
|
268
|
+
OperationId: ai_guard_post_v1beta_config
|
269
|
+
"""
|
270
|
+
return await self.request.post("v1beta/config", data={"id": id}, result_class=ServiceConfig)
|
271
|
+
|
272
|
+
async def create_service_config(
|
273
|
+
self,
|
274
|
+
name: str,
|
275
|
+
*,
|
276
|
+
id: str | None = None,
|
277
|
+
audit_data_activity: AuditDataActivityConfig | None = None,
|
278
|
+
connections: ConnectionsConfig | None = None,
|
279
|
+
recipes: Mapping[str, RecipeConfig] | None = None,
|
280
|
+
) -> PangeaResponse[ServiceConfig]:
|
281
|
+
"""
|
282
|
+
OperationId: ai_guard_post_v1beta_config_create
|
283
|
+
"""
|
284
|
+
return await self.request.post(
|
285
|
+
"v1beta/config/create",
|
286
|
+
data={
|
287
|
+
"name": name,
|
288
|
+
"id": id,
|
289
|
+
"audit_data_activity": audit_data_activity,
|
290
|
+
"connections": connections,
|
291
|
+
"recipes": recipes,
|
292
|
+
},
|
293
|
+
result_class=ServiceConfig,
|
294
|
+
)
|
295
|
+
|
296
|
+
async def update_service_config(
|
297
|
+
self,
|
298
|
+
id: str,
|
299
|
+
name: str,
|
300
|
+
*,
|
301
|
+
audit_data_activity: AuditDataActivityConfig | None = None,
|
302
|
+
connections: ConnectionsConfig | None = None,
|
303
|
+
recipes: Mapping[str, RecipeConfig] | None = None,
|
304
|
+
) -> PangeaResponse[ServiceConfig]:
|
305
|
+
"""
|
306
|
+
OperationId: ai_guard_post_v1beta_config_update
|
307
|
+
"""
|
308
|
+
return await self.request.post(
|
309
|
+
"v1beta/config/update",
|
310
|
+
data={
|
311
|
+
"id": id,
|
312
|
+
"name": name,
|
313
|
+
"audit_data_activity": audit_data_activity,
|
314
|
+
"connections": connections,
|
315
|
+
"recipes": recipes,
|
316
|
+
},
|
317
|
+
result_class=ServiceConfig,
|
318
|
+
)
|
319
|
+
|
320
|
+
async def delete_service_config(self, id: str) -> PangeaResponse[ServiceConfig]:
|
321
|
+
"""
|
322
|
+
OperationId: ai_guard_post_v1beta_config_delete
|
323
|
+
"""
|
324
|
+
return await self.request.post("v1beta/config/delete", data={"id": id}, result_class=ServiceConfig)
|
325
|
+
|
326
|
+
async def list_service_configs(
|
327
|
+
self,
|
328
|
+
*,
|
329
|
+
filter: ServiceConfigFilter | None = None,
|
330
|
+
last: str | None = None,
|
331
|
+
order: Literal["asc", "desc"] | None = None,
|
332
|
+
order_by: Literal["id", "created_at", "updated_at"] | None = None,
|
333
|
+
size: int | None = None,
|
334
|
+
) -> PangeaResponse[ServiceConfigsPage]:
|
335
|
+
"""
|
336
|
+
OperationId: ai_guard_post_v1beta_config_list
|
337
|
+
"""
|
338
|
+
return await self.request.post(
|
339
|
+
"v1beta/config/list",
|
340
|
+
data={"filter": filter, "last": last, "order": order, "order_by": order_by, "size": size},
|
341
|
+
result_class=ServiceConfigsPage,
|
342
|
+
)
|