enkryptai-sdk 1.0.24__py3-none-any.whl → 1.0.26__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.
- enkryptai_sdk/__init__.py +63 -5
- enkryptai_sdk/dto/__init__.py +9 -0
- enkryptai_sdk/dto/datasets.py +66 -16
- enkryptai_sdk/dto/models.py +81 -17
- enkryptai_sdk/dto/red_team.py +396 -82
- enkryptai_sdk/red_team.py +270 -58
- enkryptai_sdk/response.py +271 -0
- enkryptai_sdk/utils/__init__.py +29 -0
- enkryptai_sdk/utils/pagination.py +384 -0
- {enkryptai_sdk-1.0.24.dist-info → enkryptai_sdk-1.0.26.dist-info}/METADATA +1 -1
- {enkryptai_sdk-1.0.24.dist-info → enkryptai_sdk-1.0.26.dist-info}/RECORD +14 -12
- {enkryptai_sdk-1.0.24.dist-info → enkryptai_sdk-1.0.26.dist-info}/WHEEL +0 -0
- {enkryptai_sdk-1.0.24.dist-info → enkryptai_sdk-1.0.26.dist-info}/licenses/LICENSE +0 -0
- {enkryptai_sdk-1.0.24.dist-info → enkryptai_sdk-1.0.26.dist-info}/top_level.txt +0 -0
enkryptai_sdk/__init__.py
CHANGED
|
@@ -7,22 +7,80 @@ from .red_team import RedTeamClient, RedTeamClientError
|
|
|
7
7
|
from .datasets import DatasetClient, DatasetClientError
|
|
8
8
|
from .deployments import DeploymentClient, DeploymentClientError
|
|
9
9
|
from .ai_proxy import AIProxyClient, AIProxyClientError
|
|
10
|
+
from .utils.pagination import (
|
|
11
|
+
PaginationInfo,
|
|
12
|
+
PaginatedResponse,
|
|
13
|
+
parse_pagination_params,
|
|
14
|
+
build_pagination_url,
|
|
15
|
+
create_paginated_response,
|
|
16
|
+
validate_pagination_params,
|
|
17
|
+
get_pagination_metadata,
|
|
18
|
+
calculate_page_info,
|
|
19
|
+
create_pagination_links,
|
|
20
|
+
apply_pagination_to_list,
|
|
21
|
+
format_pagination_response
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
# Import DTOs
|
|
25
|
+
from .dto.models import (
|
|
26
|
+
ModelProviders,
|
|
27
|
+
AuthData,
|
|
28
|
+
BoxAIAuthData,
|
|
29
|
+
ModelConfigDetails,
|
|
30
|
+
DetailModelConfig,
|
|
31
|
+
ModelDetailConfig,
|
|
32
|
+
PathsConfig,
|
|
33
|
+
EndpointConfig,
|
|
34
|
+
ModelResponse,
|
|
35
|
+
InputModality,
|
|
36
|
+
OutputModality
|
|
37
|
+
)
|
|
10
38
|
|
|
11
39
|
__all__ = [
|
|
40
|
+
# Clients
|
|
12
41
|
"GuardrailsClient",
|
|
13
42
|
"GuardrailsClientError",
|
|
14
|
-
"
|
|
15
|
-
"CoCClient",
|
|
43
|
+
"CoCClient",
|
|
16
44
|
"CoCClientError",
|
|
17
45
|
"EvalsClient",
|
|
18
46
|
"ModelClient",
|
|
19
|
-
"RedTeamClient",
|
|
20
|
-
"DatasetClient",
|
|
21
|
-
"DeploymentClient",
|
|
22
47
|
"ModelClientError",
|
|
48
|
+
"RedTeamClient",
|
|
23
49
|
"RedTeamClientError",
|
|
50
|
+
"DatasetClient",
|
|
24
51
|
"DatasetClientError",
|
|
52
|
+
"DeploymentClient",
|
|
25
53
|
"DeploymentClientError",
|
|
26
54
|
"AIProxyClient",
|
|
27
55
|
"AIProxyClientError",
|
|
56
|
+
"EvalsClient",
|
|
57
|
+
|
|
58
|
+
# Config
|
|
59
|
+
"GuardrailsConfig",
|
|
60
|
+
|
|
61
|
+
# Pagination utilities
|
|
62
|
+
"PaginationInfo",
|
|
63
|
+
"PaginatedResponse",
|
|
64
|
+
"parse_pagination_params",
|
|
65
|
+
"build_pagination_url",
|
|
66
|
+
"create_paginated_response",
|
|
67
|
+
"validate_pagination_params",
|
|
68
|
+
"get_pagination_metadata",
|
|
69
|
+
"calculate_page_info",
|
|
70
|
+
"create_pagination_links",
|
|
71
|
+
"apply_pagination_to_list",
|
|
72
|
+
"format_pagination_response",
|
|
73
|
+
|
|
74
|
+
# DTOs
|
|
75
|
+
"ModelProviders",
|
|
76
|
+
"AuthData",
|
|
77
|
+
"BoxAIAuthData",
|
|
78
|
+
"ModelConfigDetails",
|
|
79
|
+
"DetailModelConfig",
|
|
80
|
+
"ModelDetailConfig",
|
|
81
|
+
"PathsConfig",
|
|
82
|
+
"EndpointConfig",
|
|
83
|
+
"ModelResponse",
|
|
84
|
+
"InputModality",
|
|
85
|
+
"OutputModality"
|
|
28
86
|
]
|
enkryptai_sdk/dto/__init__.py
CHANGED
|
@@ -10,6 +10,7 @@ from .coc import *
|
|
|
10
10
|
__all__ = [
|
|
11
11
|
"RedteamHealthResponse",
|
|
12
12
|
"RedTeamModelHealthConfig",
|
|
13
|
+
"RedTeamModelHealthConfigV3",
|
|
13
14
|
"RedteamModelHealthResponse",
|
|
14
15
|
"DetailModelConfig",
|
|
15
16
|
"ModelConfig",
|
|
@@ -25,6 +26,14 @@ __all__ = [
|
|
|
25
26
|
"DEFAULT_REDTEAM_CONFIG_WITH_SAVED_MODEL",
|
|
26
27
|
"DEFAULT_CUSTOM_REDTEAM_CONFIG",
|
|
27
28
|
"DEFAULT_CUSTOM_REDTEAM_CONFIG_WITH_SAVED_MODEL",
|
|
29
|
+
# V3 additions
|
|
30
|
+
"AttackMethodsV3",
|
|
31
|
+
"TestConfigV3",
|
|
32
|
+
"RedTeamTestConfigurationsV3",
|
|
33
|
+
"RedTeamCustomConfigV3",
|
|
34
|
+
"RedTeamCustomConfigWithSavedModelV3",
|
|
35
|
+
"DEFAULT_CUSTOM_REDTEAM_CONFIG_V3",
|
|
36
|
+
"DEFAULT_CUSTOM_REDTEAM_CONFIG_WITH_SAVED_MODEL_V3",
|
|
28
37
|
"ADVANCED_REDTEAM_TESTS",
|
|
29
38
|
"DETAIL_MODEL_CONFIG",
|
|
30
39
|
"DatasetConfig",
|
enkryptai_sdk/dto/datasets.py
CHANGED
|
@@ -10,32 +10,78 @@ class Tool(BaseDTO):
|
|
|
10
10
|
|
|
11
11
|
@classmethod
|
|
12
12
|
def from_dict(cls, data: Dict[str, Any]) -> "Tool":
|
|
13
|
-
return cls(
|
|
14
|
-
name=data.get("name", ""),
|
|
15
|
-
description=data.get("description", "")
|
|
16
|
-
)
|
|
13
|
+
return cls(name=data.get("name", ""), description=data.get("description", ""))
|
|
17
14
|
|
|
18
15
|
def to_dict(self) -> Dict[str, Any]:
|
|
19
|
-
return {
|
|
20
|
-
"name": self.name,
|
|
21
|
-
"description": self.description
|
|
22
|
-
}
|
|
16
|
+
return {"name": self.name, "description": self.description}
|
|
23
17
|
|
|
24
18
|
|
|
25
19
|
@dataclass
|
|
26
20
|
class DatasetConfig(BaseDTO):
|
|
27
|
-
system_description: str = None
|
|
28
|
-
dataset_name: str = None
|
|
29
|
-
policy_description: str = None
|
|
30
|
-
risk_categories: str = None
|
|
31
|
-
tools: List[Tool] = None
|
|
32
|
-
info_pdf_url: str = None
|
|
21
|
+
system_description: Optional[str] = None
|
|
22
|
+
dataset_name: Optional[str] = None
|
|
23
|
+
policy_description: Optional[str] = None
|
|
24
|
+
risk_categories: Optional[str] = None
|
|
25
|
+
tools: Optional[List[Tool]] = None
|
|
26
|
+
info_pdf_url: Optional[str] = None
|
|
33
27
|
max_prompts: int = 100
|
|
34
28
|
scenarios: int = 2
|
|
35
29
|
categories: int = 2
|
|
36
30
|
depth: int = 2
|
|
37
31
|
_extra_fields: Dict[str, Any] = field(default_factory=dict)
|
|
38
32
|
|
|
33
|
+
@classmethod
|
|
34
|
+
def from_dict(cls, data: Dict[str, Any]) -> "DatasetConfig":
|
|
35
|
+
# Handle tools conversion if present
|
|
36
|
+
tools = None
|
|
37
|
+
if "tools" in data and data["tools"] is not None:
|
|
38
|
+
tools = [
|
|
39
|
+
Tool.from_dict(tool) if isinstance(tool, dict) else tool
|
|
40
|
+
for tool in data["tools"]
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
return cls(
|
|
44
|
+
system_description=data.get("system_description"),
|
|
45
|
+
dataset_name=data.get("dataset_name"),
|
|
46
|
+
policy_description=data.get("policy_description"),
|
|
47
|
+
risk_categories=data.get("risk_categories"),
|
|
48
|
+
tools=tools,
|
|
49
|
+
info_pdf_url=data.get("info_pdf_url"),
|
|
50
|
+
max_prompts=data.get("max_prompts", 100),
|
|
51
|
+
scenarios=data.get("scenarios", 2),
|
|
52
|
+
categories=data.get("categories", 2),
|
|
53
|
+
depth=data.get("depth", 2),
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
57
|
+
result = {}
|
|
58
|
+
|
|
59
|
+
# Only include optional fields if they are not None
|
|
60
|
+
if self.system_description is not None:
|
|
61
|
+
result["system_description"] = self.system_description
|
|
62
|
+
if self.dataset_name is not None:
|
|
63
|
+
result["dataset_name"] = self.dataset_name
|
|
64
|
+
if self.policy_description is not None:
|
|
65
|
+
result["policy_description"] = self.policy_description
|
|
66
|
+
if self.risk_categories is not None:
|
|
67
|
+
result["risk_categories"] = self.risk_categories
|
|
68
|
+
if self.tools is not None:
|
|
69
|
+
result["tools"] = [
|
|
70
|
+
tool.to_dict() if hasattr(tool, "to_dict") else tool
|
|
71
|
+
for tool in self.tools
|
|
72
|
+
]
|
|
73
|
+
if self.info_pdf_url is not None:
|
|
74
|
+
result["info_pdf_url"] = self.info_pdf_url
|
|
75
|
+
|
|
76
|
+
# Always include fields with default values
|
|
77
|
+
result["max_prompts"] = self.max_prompts
|
|
78
|
+
result["scenarios"] = self.scenarios
|
|
79
|
+
result["categories"] = self.categories
|
|
80
|
+
result["depth"] = self.depth
|
|
81
|
+
|
|
82
|
+
result.update(self._extra_fields)
|
|
83
|
+
return result
|
|
84
|
+
|
|
39
85
|
|
|
40
86
|
@dataclass
|
|
41
87
|
class DatasetCollection(BaseDTO):
|
|
@@ -63,7 +109,9 @@ class DatasetResponse(BaseDTO):
|
|
|
63
109
|
|
|
64
110
|
@classmethod
|
|
65
111
|
def from_dict(cls, data: Dict[str, Any]) -> "DatasetResponse":
|
|
66
|
-
dataset_items = [
|
|
112
|
+
dataset_items = [
|
|
113
|
+
DatasetDataPoint.from_dict(item) for item in data.get("dataset", [])
|
|
114
|
+
]
|
|
67
115
|
return cls(dataset=dataset_items)
|
|
68
116
|
|
|
69
117
|
def to_dict(self) -> Dict[str, Any]:
|
|
@@ -149,7 +197,9 @@ class DatasetTaskStatus(BaseDTO):
|
|
|
149
197
|
|
|
150
198
|
@classmethod
|
|
151
199
|
def from_dict(cls, data: Dict[str, Any]) -> "DatasetTaskStatus":
|
|
152
|
-
return cls(
|
|
200
|
+
return cls(
|
|
201
|
+
status=data.get("status", ""), dataset_name=data.get("dataset_name", "")
|
|
202
|
+
)
|
|
153
203
|
|
|
154
204
|
def to_dict(self) -> Dict[str, Any]:
|
|
155
205
|
return {"status": self.status, "dataset_name": self.dataset_name}
|
enkryptai_sdk/dto/models.py
CHANGED
|
@@ -42,6 +42,9 @@ class ModelProviders(str, Enum):
|
|
|
42
42
|
HR = "hr"
|
|
43
43
|
URL = "url"
|
|
44
44
|
ENKRYPTAI = "enkryptai"
|
|
45
|
+
BOXAI = "boxai"
|
|
46
|
+
NUTANIX = "nutanix"
|
|
47
|
+
XACTLY = "xactly"
|
|
45
48
|
|
|
46
49
|
|
|
47
50
|
@dataclass
|
|
@@ -88,6 +91,55 @@ class AuthData(BaseDTO):
|
|
|
88
91
|
return cls(**data)
|
|
89
92
|
|
|
90
93
|
|
|
94
|
+
@dataclass
|
|
95
|
+
class BoxAIAuthData(AuthData):
|
|
96
|
+
"""BoxAI-specific authentication data."""
|
|
97
|
+
|
|
98
|
+
boxai_client_id: Optional[str] = None
|
|
99
|
+
boxai_client_secret: Optional[str] = None
|
|
100
|
+
boxai_user_id: Optional[str] = None
|
|
101
|
+
boxai_default_file_id: Optional[str] = None
|
|
102
|
+
|
|
103
|
+
def __post_init__(self):
|
|
104
|
+
# Store BoxAI fields in extra_fields for backward compatibility
|
|
105
|
+
if self.boxai_client_id:
|
|
106
|
+
self._extra_fields["boxai_client_id"] = self.boxai_client_id
|
|
107
|
+
if self.boxai_client_secret:
|
|
108
|
+
self._extra_fields["boxai_client_secret"] = self.boxai_client_secret
|
|
109
|
+
if self.boxai_user_id:
|
|
110
|
+
self._extra_fields["boxai_user_id"] = self.boxai_user_id
|
|
111
|
+
if self.boxai_default_file_id:
|
|
112
|
+
self._extra_fields["boxai_default_file_id"] = self.boxai_default_file_id
|
|
113
|
+
|
|
114
|
+
@classmethod
|
|
115
|
+
def from_dict(cls, data: dict):
|
|
116
|
+
# Extract BoxAI fields from extra_fields if they exist
|
|
117
|
+
boxai_data = {}
|
|
118
|
+
if "_extra_fields" in data:
|
|
119
|
+
extra_fields = data["_extra_fields"]
|
|
120
|
+
for field in [
|
|
121
|
+
"boxai_client_id",
|
|
122
|
+
"boxai_client_secret",
|
|
123
|
+
"boxai_user_id",
|
|
124
|
+
"boxai_default_file_id",
|
|
125
|
+
]:
|
|
126
|
+
if field in extra_fields:
|
|
127
|
+
boxai_data[field] = extra_fields[field]
|
|
128
|
+
|
|
129
|
+
# Merge with direct field values
|
|
130
|
+
for field in [
|
|
131
|
+
"boxai_client_id",
|
|
132
|
+
"boxai_client_secret",
|
|
133
|
+
"boxai_user_id",
|
|
134
|
+
"boxai_default_file_id",
|
|
135
|
+
]:
|
|
136
|
+
if field in data:
|
|
137
|
+
boxai_data[field] = data[field]
|
|
138
|
+
|
|
139
|
+
# Create the instance
|
|
140
|
+
return cls(**boxai_data)
|
|
141
|
+
|
|
142
|
+
|
|
91
143
|
@dataclass
|
|
92
144
|
class ModelDetailConfig:
|
|
93
145
|
model_source: str = ""
|
|
@@ -129,8 +181,8 @@ class OutputModality(str, Enum):
|
|
|
129
181
|
|
|
130
182
|
@dataclass
|
|
131
183
|
class ModelConfigDetails(BaseDTO):
|
|
132
|
-
model_id: str = None
|
|
133
|
-
model_source: str = None
|
|
184
|
+
model_id: Optional[str] = None
|
|
185
|
+
model_source: Optional[str] = None
|
|
134
186
|
# model_provider: str = "openai"
|
|
135
187
|
model_provider: ModelProviders = ModelProviders.OPENAI
|
|
136
188
|
model_api_value: str = ""
|
|
@@ -168,21 +220,29 @@ class ModelConfigDetails(BaseDTO):
|
|
|
168
220
|
data = data.copy()
|
|
169
221
|
|
|
170
222
|
if "custom_headers" in data:
|
|
171
|
-
data["custom_headers"] = [
|
|
223
|
+
data["custom_headers"] = [
|
|
224
|
+
CustomHeader.from_dict(h) for h in data["custom_headers"]
|
|
225
|
+
]
|
|
172
226
|
|
|
173
227
|
if "model_auth_type" in data:
|
|
174
228
|
data["model_auth_type"] = ModelAuthTypeEnum(data["model_auth_type"])
|
|
175
229
|
|
|
176
230
|
if "model_jwt_config" in data:
|
|
177
|
-
data["model_jwt_config"] = ModelJwtConfig.from_dict(
|
|
231
|
+
data["model_jwt_config"] = ModelJwtConfig.from_dict(
|
|
232
|
+
data["model_jwt_config"]
|
|
233
|
+
)
|
|
178
234
|
|
|
179
235
|
# Convert input_modalities strings to enum values
|
|
180
236
|
if "input_modalities" in data:
|
|
181
|
-
data["input_modalities"] = [
|
|
182
|
-
|
|
237
|
+
data["input_modalities"] = [
|
|
238
|
+
InputModality(m) for m in data["input_modalities"]
|
|
239
|
+
]
|
|
240
|
+
|
|
183
241
|
# Convert output_modalities strings to enum values
|
|
184
242
|
if "output_modalities" in data:
|
|
185
|
-
data["output_modalities"] = [
|
|
243
|
+
data["output_modalities"] = [
|
|
244
|
+
OutputModality(m) for m in data["output_modalities"]
|
|
245
|
+
]
|
|
186
246
|
|
|
187
247
|
# Validate model_provider if present
|
|
188
248
|
if "model_provider" in data:
|
|
@@ -193,11 +253,15 @@ class ModelConfigDetails(BaseDTO):
|
|
|
193
253
|
data["model_provider"] = ModelProviders(provider)
|
|
194
254
|
except ValueError:
|
|
195
255
|
valid_providers = [p.value for p in ModelProviders]
|
|
196
|
-
raise ValueError(
|
|
256
|
+
raise ValueError(
|
|
257
|
+
f"Invalid model_provider: '{provider}'. Must be one of: {valid_providers}"
|
|
258
|
+
)
|
|
197
259
|
# If it's already an enum instance, keep it as is
|
|
198
260
|
elif not isinstance(provider, ModelProviders):
|
|
199
261
|
valid_providers = [p.value for p in ModelProviders]
|
|
200
|
-
raise ValueError(
|
|
262
|
+
raise ValueError(
|
|
263
|
+
f"Invalid model_provider type. Valid values: {valid_providers}"
|
|
264
|
+
)
|
|
201
265
|
|
|
202
266
|
# # Remove known fields that we don't want in our model
|
|
203
267
|
# unwanted_fields = ["queryParams"]
|
|
@@ -266,16 +330,16 @@ class ModelConfigDetails(BaseDTO):
|
|
|
266
330
|
|
|
267
331
|
@dataclass
|
|
268
332
|
class ModelConfig(BaseDTO):
|
|
269
|
-
created_at: str = None
|
|
270
|
-
updated_at: str = None
|
|
271
|
-
created_by: str = None
|
|
272
|
-
updated_by: str = None
|
|
273
|
-
model_id: str = None
|
|
274
|
-
model_saved_name: str = None
|
|
275
|
-
model_version: str = None
|
|
333
|
+
created_at: Optional[str] = None
|
|
334
|
+
updated_at: Optional[str] = None
|
|
335
|
+
created_by: Optional[str] = None
|
|
336
|
+
updated_by: Optional[str] = None
|
|
337
|
+
model_id: Optional[str] = None
|
|
338
|
+
model_saved_name: Optional[str] = None
|
|
339
|
+
model_version: Optional[str] = None
|
|
276
340
|
testing_for: str = "foundationModels"
|
|
277
341
|
# modality: Modality = Modality.TEXT
|
|
278
|
-
project_name: str = None
|
|
342
|
+
project_name: Optional[str] = None
|
|
279
343
|
model_name: Optional[str] = "gpt-4o-mini"
|
|
280
344
|
certifications: List[str] = field(default_factory=list)
|
|
281
345
|
model_config: ModelConfigDetails = field(default_factory=ModelConfigDetails)
|