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 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
- "GuardrailsConfig",
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
  ]
@@ -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",
@@ -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 = [DatasetDataPoint.from_dict(item) for item in data.get("dataset", [])]
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(status=data.get("status", ""), dataset_name=data.get("dataset_name", ""))
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}
@@ -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"] = [CustomHeader.from_dict(h) for h in 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(data["model_jwt_config"])
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"] = [InputModality(m) for m in 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"] = [OutputModality(m) for m in 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(f"Invalid model_provider: '{provider}'. Must be one of: {valid_providers}")
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(f"Invalid model_provider type. Valid values: {valid_providers}")
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)