enkryptai-sdk 0.1.6__py3-none-any.whl → 0.1.7__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.
@@ -1,85 +1,219 @@
1
+ import pandas as pd
2
+ from .base import BaseDTO
3
+ from typing import Dict, List, Optional, Any
1
4
  from dataclasses import dataclass, field, asdict
2
- from typing import Dict, List, Optional
3
- import json
4
5
 
5
6
 
6
7
  @dataclass
7
- class RedTeamResponse:
8
- task_id: Optional[str] = None
8
+ class RedteamHealthResponse(BaseDTO):
9
+ status: str
10
+ _extra_fields: Dict[str, Any] = field(default_factory=dict)
11
+
12
+ @classmethod
13
+ def from_dict(cls, data: Dict[str, Any]) -> "RedteamHealthResponse":
14
+ return cls(
15
+ status=data.get("status", "")
16
+ )
17
+
18
+ def to_dict(self) -> Dict[str, Any]:
19
+ return {
20
+ "status": self.status
21
+ }
9
22
 
10
- def to_dict(self) -> dict:
11
- return asdict(self)
23
+
24
+ @dataclass
25
+ class RedTeamResponse(BaseDTO):
26
+ task_id: Optional[str] = None
27
+ message: Optional[str] = None
28
+ data: Optional[Dict[str, Any]] = None
29
+ _extra_fields: Dict[str, Any] = field(default_factory=dict)
12
30
 
13
31
  @classmethod
14
- def from_dict(cls, data: dict):
15
- return cls(**data)
32
+ def from_dict(cls, data: Dict) -> "RedTeamResponse":
33
+ return cls(
34
+ task_id=data.get("task_id"),
35
+ message=data.get("message"),
36
+ data=data.get("data"),
37
+ )
38
+
39
+ def to_dict(self) -> Dict:
40
+ return super().to_dict()
16
41
 
17
42
 
18
43
  @dataclass
19
- class RedTeamTaskStatus:
44
+ class RedTeamTaskStatus(BaseDTO):
20
45
  status: Optional[str] = None
21
46
 
22
- def to_dict(self) -> dict:
23
- return asdict(self)
24
-
25
- @classmethod
26
- def from_dict(cls, data: dict):
27
- return cls(**data)
28
-
29
47
 
30
48
  @dataclass
31
- class RedTeamTaskDetails:
49
+ class RedTeamTaskDetails(BaseDTO):
32
50
  created_at: Optional[str] = None
33
51
  model_name: Optional[str] = None
34
52
  status: Optional[str] = None
53
+ test_name: Optional[str] = None
35
54
  task_id: Optional[str] = None
36
55
 
37
- def to_dict(self) -> dict:
38
- return asdict(self)
56
+
57
+ @dataclass
58
+ class StatisticItem(BaseDTO):
59
+ success_percentage: float
60
+ total: int
61
+ _extra_fields: Dict[str, Any] = field(default_factory=dict)
39
62
 
40
63
  @classmethod
41
- def from_dict(cls, data: dict):
42
- return cls(**data)
64
+ def from_dict(cls, data: Dict) -> "StatisticItem":
65
+ return cls(
66
+ success_percentage=data.get("success(%)", 0.0), total=data.get("total", 0)
67
+ )
68
+
69
+ def to_dict(self) -> Dict:
70
+ d = super().to_dict()
71
+ # Special handling for success percentage key
72
+ d["success(%)"] = d.pop("success_percentage")
73
+ return d
43
74
 
44
75
 
45
76
  @dataclass
46
- class RedTeamResultSummary:
47
- test_date: Optional[str] = None
48
- test_name: Optional[str] = None
49
- dataset_name: Optional[str] = None
50
- model_name: Optional[str] = None
51
- model_endpoint_url: Optional[str] = None
52
- model_source: Optional[str] = None
53
- model_provider: Optional[str] = None
54
- risk_score: Optional[float] = None
55
- test_type: Optional[List] = None
56
- nist_category: Optional[List] = None
57
- scenario: Optional[List] = None
58
- category: Optional[List] = None
59
- attack_method: Optional[List] = None
77
+ class ResultSummary(BaseDTO):
78
+ test_date: str
79
+ test_name: str
80
+ dataset_name: str
81
+ model_name: str
82
+ model_endpoint_url: str
83
+ model_source: str
84
+ model_provider: str
85
+ risk_score: float
86
+ test_type: Dict[str, StatisticItem]
87
+ nist_category: Dict[str, StatisticItem]
88
+ scenario: Dict[str, StatisticItem]
89
+ category: Dict[str, StatisticItem]
90
+ attack_method: Dict[str, StatisticItem]
91
+ _extra_fields: Dict[str, Any] = field(default_factory=dict)
60
92
 
61
- def to_dict(self) -> dict:
62
- return asdict(self)
93
+ @classmethod
94
+ def from_dict(cls, data: Dict) -> "ResultSummary":
95
+ def convert_stat_list(stat_list: List[Dict]) -> Dict[str, StatisticItem]:
96
+ result = {}
97
+ for item in stat_list:
98
+ for key, value in item.items():
99
+ result[key] = StatisticItem.from_dict(value)
100
+ return result
101
+
102
+ return cls(
103
+ test_date=data.get("test_date", ""),
104
+ test_name=data.get("test_name", ""),
105
+ dataset_name=data.get("dataset_name", ""),
106
+ model_name=data.get("model_name", ""),
107
+ model_endpoint_url=data.get("model_endpoint_url", ""),
108
+ model_source=data.get("model_source", ""),
109
+ model_provider=data.get("model_provider", ""),
110
+ risk_score=data.get("risk_score", 0.0),
111
+ test_type=convert_stat_list(data.get("test_type", [])),
112
+ nist_category=convert_stat_list(data.get("nist_category", [])),
113
+ scenario=convert_stat_list(data.get("scenario", [])),
114
+ category=convert_stat_list(data.get("category", [])),
115
+ attack_method=convert_stat_list(data.get("attack_method", [])),
116
+ )
117
+
118
+ def to_dict(self) -> Dict:
119
+ def convert_stat_dict(stat_dict: Dict[str, StatisticItem]) -> List[Dict]:
120
+ return [{key: value.to_dict()} for key, value in stat_dict.items()]
121
+
122
+ d = super().to_dict()
123
+ # Convert stat dictionaries to lists of dictionaries
124
+ d["test_type"] = convert_stat_dict(self.test_type)
125
+ d["nist_category"] = convert_stat_dict(self.nist_category)
126
+ d["scenario"] = convert_stat_dict(self.scenario)
127
+ d["category"] = convert_stat_dict(self.category)
128
+ d["attack_method"] = convert_stat_dict(self.attack_method)
129
+ return d
130
+
131
+
132
+ @dataclass
133
+ class RedTeamResultSummary(BaseDTO):
134
+ summary: ResultSummary
135
+ _extra_fields: Dict[str, Any] = field(default_factory=dict)
63
136
 
64
137
  @classmethod
65
- def from_dict(cls, data: dict):
66
- return cls(**data)
138
+ def from_dict(cls, data: Dict) -> "RedTeamResultSummary":
139
+ if not data or "summary" not in data:
140
+ return cls(summary=ResultSummary.from_dict({}))
141
+ return cls(summary=ResultSummary.from_dict(data["summary"]))
142
+
143
+ def to_dict(self) -> Dict:
144
+ return {"summary": self.summary.to_dict()}
67
145
 
68
146
 
69
147
  @dataclass
70
- class RedTeamResultDetails: # To Be Updated
71
- details: Optional[Dict] = None
148
+ class TestEvalTokens(BaseDTO):
149
+ prompt_tokens: int
150
+ completion_tokens: int
151
+ total_tokens: int
152
+ _extra_fields: Dict[str, Any] = field(default_factory=dict)
153
+
154
+
155
+ @dataclass
156
+ class TestResult(BaseDTO):
157
+ prompt: str
158
+ category: str
159
+ test_type: str
160
+ nist_category: str
161
+ source: str
162
+ attack_method: str
163
+ jailbreak_prompt: str
164
+ response: str
165
+ success: str
166
+ reasoning: str
167
+ detected_language: str
168
+ eval_latency: float
169
+ eval_tokens: TestEvalTokens
170
+ test_name: str
171
+ _extra_fields: Dict[str, Any] = field(default_factory=dict)
72
172
 
73
- def to_dict(self) -> dict:
74
- return asdict(self)
173
+
174
+ @dataclass
175
+ class RedTeamResultDetails(BaseDTO):
176
+ details: List[TestResult]
177
+ _extra_fields: Dict[str, Any] = field(default_factory=dict)
75
178
 
76
179
  @classmethod
77
- def from_dict(cls, data: dict):
78
- return cls(**data)
180
+ def from_dict(cls, data: Dict) -> "RedTeamResultDetails":
181
+ if not data or "details" not in data:
182
+ return cls(details=[])
183
+
184
+ details = []
185
+ for result in data["details"]:
186
+ # Convert eval_tokens dict to TestEvalTokens object
187
+ eval_tokens = TestEvalTokens(**result["eval_tokens"])
188
+
189
+ # Create a copy of the result dict and replace eval_tokens
190
+ result_copy = dict(result)
191
+ result_copy["eval_tokens"] = eval_tokens
192
+
193
+ # Create TestResult object
194
+ test_result = TestResult(**result_copy)
195
+ details.append(test_result)
196
+
197
+ return cls(details=details)
198
+
199
+ def to_dict(self) -> Dict:
200
+ return {
201
+ "details": [
202
+ {**result.to_dict(), "eval_tokens": result.eval_tokens.to_dict()}
203
+ for result in self.details
204
+ ]
205
+ }
206
+
207
+ def to_dataframe(self) -> pd.DataFrame:
208
+ data = [
209
+ {**result.to_dict(), "eval_tokens": result.eval_tokens.to_dict()}
210
+ for result in self.details
211
+ ]
212
+ return pd.DataFrame(data)
79
213
 
80
214
 
81
215
  @dataclass
82
- class AttackMethods:
216
+ class AttackMethods(BaseDTO):
83
217
  basic: List[str] = field(default_factory=lambda: ["basic"])
84
218
  advanced: Dict[str, List[str]] = field(
85
219
  default_factory=lambda: {"static": ["single_shot"], "dynamic": ["iterative"]}
@@ -94,7 +228,7 @@ class AttackMethods:
94
228
 
95
229
 
96
230
  @dataclass
97
- class TestConfig:
231
+ class TestConfig(BaseDTO):
98
232
  sample_percentage: int = 100
99
233
  attack_methods: AttackMethods = field(default_factory=AttackMethods)
100
234
 
@@ -111,7 +245,7 @@ class TestConfig:
111
245
 
112
246
 
113
247
  @dataclass
114
- class RedTeamTestConfigurations:
248
+ class RedTeamTestConfigurations(BaseDTO):
115
249
  # Basic tests
116
250
  bias_test: TestConfig = field(default=None)
117
251
  cbrn_test: TestConfig = field(default=None)
@@ -122,9 +256,7 @@ class RedTeamTestConfigurations:
122
256
  adv_info_test: TestConfig = field(default=None)
123
257
  adv_bias_test: TestConfig = field(default=None)
124
258
  adv_command_test: TestConfig = field(default=None)
125
-
126
- def to_dict(self) -> dict:
127
- return asdict(self)
259
+ _extra_fields: Dict[str, Any] = field(default_factory=dict)
128
260
 
129
261
  @classmethod
130
262
  def from_dict(cls, data: dict):
@@ -132,9 +264,10 @@ class RedTeamTestConfigurations:
132
264
 
133
265
 
134
266
  @dataclass
135
- class TargetModelConfiguration:
267
+ class TargetModelConfiguration(BaseDTO):
136
268
  testing_for: str = "LLM"
137
269
  model_name: str = "gpt-4o-mini"
270
+ model_type: str = "text_2_text"
138
271
  model_version: Optional[str] = None
139
272
  system_prompt: str = ""
140
273
  conversation_template: str = ""
@@ -142,20 +275,63 @@ class TargetModelConfiguration:
142
275
  model_provider: str = "openai"
143
276
  model_endpoint_url: str = "https://api.openai.com/v1/chat/completions"
144
277
  model_api_key: Optional[str] = None
278
+ rate_per_min: int = 20
279
+ _extra_fields: Dict[str, Any] = field(default_factory=dict)
280
+
281
+ @classmethod
282
+ def from_dict(cls, data: dict):
283
+ return cls(**data)
284
+
285
+
286
+ @dataclass
287
+ class RedTeamModelHealthConfig(BaseDTO):
288
+ target_model_configuration: TargetModelConfiguration = field(
289
+ default_factory=TargetModelConfiguration
290
+ )
145
291
 
146
292
  def to_dict(self) -> dict:
147
- return asdict(self)
293
+ d = asdict(self)
294
+ d["target_model_configuration"] = self.target_model_configuration.to_dict()
295
+ return d
148
296
 
149
297
  @classmethod
150
298
  def from_dict(cls, data: dict):
151
- return cls(**data)
299
+ data = data.copy()
300
+ target_config = TargetModelConfiguration.from_dict(
301
+ data.pop("target_model_configuration", {})
302
+ )
303
+ return cls(
304
+ # **data,
305
+ target_model_configuration=target_config,
306
+ )
152
307
 
153
308
 
154
309
  @dataclass
155
- class RedTeamConfig:
310
+ class RedteamModelHealthResponse(BaseDTO):
311
+ status: str
312
+ error: str
313
+ _extra_fields: Dict[str, Any] = field(default_factory=dict)
314
+
315
+ @classmethod
316
+ def from_dict(cls, data: Dict[str, Any]) -> "RedteamModelHealthResponse":
317
+ return cls(
318
+ status=data.get("status", ""),
319
+ error=data.get("error", "")
320
+ )
321
+
322
+ def to_dict(self) -> Dict[str, Any]:
323
+ return {
324
+ "status": self.status,
325
+ "error": self.error
326
+ }
327
+
328
+
329
+ @dataclass
330
+ class RedTeamConfig(BaseDTO):
156
331
  test_name: str = "Test Name"
157
332
  dataset_name: str = "standard"
158
- model_name: str = "gpt-4o-mini"
333
+ model_saved_name: str = "gpt-4o-mini"
334
+
159
335
  redteam_test_configurations: RedTeamTestConfigurations = field(
160
336
  default_factory=RedTeamTestConfigurations
161
337
  )
@@ -163,15 +339,14 @@ class RedTeamConfig:
163
339
  default_factory=TargetModelConfiguration
164
340
  )
165
341
 
342
+ _extra_fields: Dict[str, Any] = field(default_factory=dict)
343
+
166
344
  def to_dict(self) -> dict:
167
345
  d = asdict(self)
168
346
  d["redteam_test_configurations"] = self.redteam_test_configurations.to_dict()
169
347
  d["target_model_configuration"] = self.target_model_configuration.to_dict()
170
348
  return d
171
349
 
172
- def to_json(self) -> str:
173
- return json.dumps(self.to_dict())
174
-
175
350
  @classmethod
176
351
  def from_dict(cls, data: dict):
177
352
  data = data.copy()
@@ -187,9 +362,51 @@ class RedTeamConfig:
187
362
  target_model_configuration=target_config,
188
363
  )
189
364
 
190
- @classmethod
191
- def from_json(cls, json_str: str):
192
- return cls.from_dict(json.loads(json_str))
365
+
366
+ # @dataclass
367
+ # class RedTeamConfigWithSavedModel(BaseDTO):
368
+ # test_name: str = "Test Name"
369
+ # dataset_name: str = "standard"
370
+ # model_saved_name: str = "gpt-4o-mini"
371
+
372
+ # redteam_test_configurations: RedTeamTestConfigurations = field(
373
+ # default_factory=RedTeamTestConfigurations
374
+ # )
375
+ # target_model_configuration: TargetModelConfiguration = field(
376
+ # default_factory=TargetModelConfiguration
377
+ # )
378
+
379
+ # _extra_fields: Dict[str, Any] = field(default_factory=dict)
380
+
381
+ # def to_dict(self) -> dict:
382
+ # d = asdict(self)
383
+ # d["redteam_test_configurations"] = self.redteam_test_configurations.to_dict()
384
+ # d["target_model_configuration"] = self.target_model_configuration.to_dict()
385
+ # return d
386
+
387
+ # @classmethod
388
+ # def from_dict(cls, data: dict):
389
+ # data = data.copy()
390
+ # test_configs = RedTeamTestConfigurations.from_dict(
391
+ # data.pop("redteam_test_configurations", {})
392
+ # )
393
+ # target_config = TargetModelConfiguration.from_dict(
394
+ # data.pop("target_model_configuration", {})
395
+ # )
396
+ # return cls(
397
+ # **data,
398
+ # redteam_test_configurations=test_configs,
399
+ # target_model_configuration=target_config,
400
+ # )
401
+
402
+
403
+ @dataclass
404
+ class RedTeamTaskList(BaseDTO):
405
+ tasks: List[RedTeamTaskDetails] = field(default_factory=list)
406
+
407
+ def to_dataframe(self) -> pd.DataFrame:
408
+ data = [task for task in self.tasks]
409
+ return pd.DataFrame(data)
193
410
 
194
411
 
195
412
  # Default configurations