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/red_team.py
CHANGED
|
@@ -6,11 +6,14 @@ from .datasets import DatasetClient
|
|
|
6
6
|
from .dto import (
|
|
7
7
|
RedteamHealthResponse,
|
|
8
8
|
RedTeamModelHealthConfig,
|
|
9
|
+
RedTeamModelHealthConfigV3,
|
|
9
10
|
RedteamModelHealthResponse,
|
|
10
11
|
RedTeamConfig,
|
|
11
12
|
RedTeamConfigWithSavedModel,
|
|
12
13
|
RedTeamCustomConfig,
|
|
13
14
|
RedTeamCustomConfigWithSavedModel,
|
|
15
|
+
RedTeamCustomConfigV3,
|
|
16
|
+
RedTeamCustomConfigWithSavedModelV3,
|
|
14
17
|
RedTeamResponse,
|
|
15
18
|
RedTeamResultSummary,
|
|
16
19
|
RedTeamResultDetails,
|
|
@@ -21,7 +24,8 @@ from .dto import (
|
|
|
21
24
|
RedTeamRiskMitigationGuardrailsPolicyResponse,
|
|
22
25
|
RedTeamRiskMitigationSystemPromptConfig,
|
|
23
26
|
RedTeamRiskMitigationSystemPromptResponse,
|
|
24
|
-
RedTeamFindingsResponse
|
|
27
|
+
RedTeamFindingsResponse,
|
|
28
|
+
RedTeamDownloadLinkResponse,
|
|
25
29
|
)
|
|
26
30
|
|
|
27
31
|
|
|
@@ -70,14 +74,16 @@ class RedTeamClient(BaseClient):
|
|
|
70
74
|
config = RedTeamModelHealthConfig.from_dict(config)
|
|
71
75
|
# Print the config as json string
|
|
72
76
|
# print(f"Config: {json.dumps(config.to_dict(), indent=4)}")
|
|
73
|
-
response = self._request(
|
|
77
|
+
response = self._request(
|
|
78
|
+
"POST", "/redteam/model-health", json=config.to_dict()
|
|
79
|
+
)
|
|
74
80
|
# if response.get("error"):
|
|
75
81
|
if response.get("error") not in [None, ""]:
|
|
76
82
|
raise RedTeamClientError(f"API Error: {str(response)}")
|
|
77
83
|
return RedteamModelHealthResponse.from_dict(response)
|
|
78
84
|
except Exception as e:
|
|
79
85
|
raise RedTeamClientError(str(e))
|
|
80
|
-
|
|
86
|
+
|
|
81
87
|
def check_saved_model_health(self, model_saved_name: str, model_version: str):
|
|
82
88
|
"""
|
|
83
89
|
Get the health status of a saved model.
|
|
@@ -87,7 +93,9 @@ class RedTeamClient(BaseClient):
|
|
|
87
93
|
"X-Enkrypt-Model": model_saved_name,
|
|
88
94
|
"X-Enkrypt-Model-Version": model_version,
|
|
89
95
|
}
|
|
90
|
-
response = self._request(
|
|
96
|
+
response = self._request(
|
|
97
|
+
"POST", "/redteam/model/model-health", headers=headers
|
|
98
|
+
)
|
|
91
99
|
# if response.get("error"):
|
|
92
100
|
if response.get("error") not in [None, ""]:
|
|
93
101
|
raise RedTeamClientError(f"API Error: {str(response)}")
|
|
@@ -95,6 +103,38 @@ class RedTeamClient(BaseClient):
|
|
|
95
103
|
except Exception as e:
|
|
96
104
|
raise RedTeamClientError(str(e))
|
|
97
105
|
|
|
106
|
+
def check_model_health_v3(self, config: RedTeamModelHealthConfigV3):
|
|
107
|
+
"""
|
|
108
|
+
Get the health status of a model using V3 format with endpoint_configuration.
|
|
109
|
+
|
|
110
|
+
This method accepts endpoint_configuration (similar to add_custom_task) and
|
|
111
|
+
converts it internally to target_model_configuration format for backend compatibility.
|
|
112
|
+
|
|
113
|
+
Args:
|
|
114
|
+
config (RedTeamModelHealthConfigV3): Configuration object containing endpoint_configuration
|
|
115
|
+
|
|
116
|
+
Returns:
|
|
117
|
+
RedteamModelHealthResponse: Response from the API containing health status
|
|
118
|
+
|
|
119
|
+
Raises:
|
|
120
|
+
RedTeamClientError: If there's an error from the API
|
|
121
|
+
"""
|
|
122
|
+
try:
|
|
123
|
+
config = RedTeamModelHealthConfigV3.from_dict(config)
|
|
124
|
+
|
|
125
|
+
# Convert endpoint_configuration to target_model_configuration
|
|
126
|
+
target_config = config.to_target_model_configuration()
|
|
127
|
+
|
|
128
|
+
# Create the payload in the format expected by the backend
|
|
129
|
+
payload = {"target_model_configuration": target_config.to_dict()}
|
|
130
|
+
|
|
131
|
+
response = self._request("POST", "/redteam/model-health", json=payload)
|
|
132
|
+
if response.get("error") not in [None, ""]:
|
|
133
|
+
raise RedTeamClientError(f"API Error: {str(response)}")
|
|
134
|
+
return RedteamModelHealthResponse.from_dict(response)
|
|
135
|
+
except Exception as e:
|
|
136
|
+
raise RedTeamClientError(str(e))
|
|
137
|
+
|
|
98
138
|
def add_task(
|
|
99
139
|
self,
|
|
100
140
|
config: RedTeamConfig,
|
|
@@ -128,9 +168,7 @@ class RedTeamClient(BaseClient):
|
|
|
128
168
|
raise RedTeamClientError(f"API Error: {str(response)}")
|
|
129
169
|
return RedTeamResponse.from_dict(response)
|
|
130
170
|
else:
|
|
131
|
-
raise RedTeamClientError(
|
|
132
|
-
"Please provide a target model configuration"
|
|
133
|
-
)
|
|
171
|
+
raise RedTeamClientError("Please provide a target model configuration")
|
|
134
172
|
|
|
135
173
|
def add_task_with_saved_model(
|
|
136
174
|
self,
|
|
@@ -143,7 +181,7 @@ class RedTeamClient(BaseClient):
|
|
|
143
181
|
"""
|
|
144
182
|
if not model_saved_name:
|
|
145
183
|
raise RedTeamClientError("Please provide a model_saved_name")
|
|
146
|
-
|
|
184
|
+
|
|
147
185
|
if not model_version:
|
|
148
186
|
raise RedTeamClientError("Please provide a model_version. Default is 'v1'")
|
|
149
187
|
|
|
@@ -200,17 +238,19 @@ class RedTeamClient(BaseClient):
|
|
|
200
238
|
"redteam_test_configurations": test_configs,
|
|
201
239
|
}
|
|
202
240
|
|
|
241
|
+
# Only add frameworks if provided and not empty
|
|
242
|
+
if config.frameworks:
|
|
243
|
+
payload["frameworks"] = config.frameworks
|
|
244
|
+
|
|
203
245
|
if config.dataset_configuration:
|
|
204
246
|
payload["dataset_configuration"] = DatasetClient.prepare_dataset_payload(
|
|
205
|
-
config.dataset_configuration, True
|
|
206
|
-
else:
|
|
207
|
-
raise RedTeamClientError(
|
|
208
|
-
"Please provide a dataset configuration"
|
|
247
|
+
config.dataset_configuration, True
|
|
209
248
|
)
|
|
210
249
|
|
|
211
250
|
if config.endpoint_configuration:
|
|
212
251
|
payload["endpoint_configuration"] = ModelClient.prepare_model_payload(
|
|
213
|
-
config.endpoint_configuration, True
|
|
252
|
+
config.endpoint_configuration, True
|
|
253
|
+
)
|
|
214
254
|
# print(payload)
|
|
215
255
|
|
|
216
256
|
response = self._request(
|
|
@@ -223,9 +263,7 @@ class RedTeamClient(BaseClient):
|
|
|
223
263
|
raise RedTeamClientError(f"API Error: {str(response)}")
|
|
224
264
|
return RedTeamResponse.from_dict(response)
|
|
225
265
|
else:
|
|
226
|
-
raise RedTeamClientError(
|
|
227
|
-
"Please provide a endpoint configuration"
|
|
228
|
-
)
|
|
266
|
+
raise RedTeamClientError("Please provide a endpoint configuration")
|
|
229
267
|
|
|
230
268
|
def add_custom_task_with_saved_model(
|
|
231
269
|
self,
|
|
@@ -239,7 +277,7 @@ class RedTeamClient(BaseClient):
|
|
|
239
277
|
"""
|
|
240
278
|
if not model_saved_name:
|
|
241
279
|
raise RedTeamClientError("Please provide a model_saved_name")
|
|
242
|
-
|
|
280
|
+
|
|
243
281
|
if not model_version:
|
|
244
282
|
raise RedTeamClientError("Please provide a model_version. Default is 'v1'")
|
|
245
283
|
|
|
@@ -254,12 +292,13 @@ class RedTeamClient(BaseClient):
|
|
|
254
292
|
"redteam_test_configurations": test_configs,
|
|
255
293
|
}
|
|
256
294
|
|
|
295
|
+
# Only add frameworks if provided and not empty
|
|
296
|
+
if config.frameworks:
|
|
297
|
+
payload["frameworks"] = config.frameworks
|
|
298
|
+
|
|
257
299
|
if config.dataset_configuration:
|
|
258
300
|
payload["dataset_configuration"] = DatasetClient.prepare_dataset_payload(
|
|
259
|
-
config.dataset_configuration, True
|
|
260
|
-
else:
|
|
261
|
-
raise RedTeamClientError(
|
|
262
|
-
"Please provide a dataset configuration"
|
|
301
|
+
config.dataset_configuration, True
|
|
263
302
|
)
|
|
264
303
|
|
|
265
304
|
headers = {
|
|
@@ -281,6 +320,140 @@ class RedTeamClient(BaseClient):
|
|
|
281
320
|
raise RedTeamClientError(f"API Error: {str(response)}")
|
|
282
321
|
return RedTeamResponse.from_dict(response)
|
|
283
322
|
|
|
323
|
+
def add_custom_task_v3(
|
|
324
|
+
self,
|
|
325
|
+
config: RedTeamCustomConfigV3,
|
|
326
|
+
policy_name: str = None,
|
|
327
|
+
):
|
|
328
|
+
"""
|
|
329
|
+
Add a new custom red teaming task with v3 attack methods format.
|
|
330
|
+
|
|
331
|
+
V3 format supports nested attack methods:
|
|
332
|
+
{
|
|
333
|
+
"test_name": {
|
|
334
|
+
"sample_percentage": 50,
|
|
335
|
+
"attack_methods": {
|
|
336
|
+
"method_category": {
|
|
337
|
+
"method_name": {
|
|
338
|
+
"params": {}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
"""
|
|
345
|
+
headers = {
|
|
346
|
+
"Content-Type": "application/json",
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
if policy_name is not None:
|
|
350
|
+
headers["X-Enkrypt-Policy"] = policy_name
|
|
351
|
+
|
|
352
|
+
config = RedTeamCustomConfigV3.from_dict(config)
|
|
353
|
+
test_configs = config.redteam_test_configurations.to_dict()
|
|
354
|
+
# Remove None or empty test configurations
|
|
355
|
+
test_configs = {k: v for k, v in test_configs.items() if v is not None}
|
|
356
|
+
|
|
357
|
+
payload = {
|
|
358
|
+
"test_name": config.test_name,
|
|
359
|
+
"redteam_test_configurations": test_configs,
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
# Only add frameworks if provided and not empty
|
|
363
|
+
if config.frameworks:
|
|
364
|
+
payload["frameworks"] = config.frameworks
|
|
365
|
+
|
|
366
|
+
if config.dataset_configuration:
|
|
367
|
+
payload["dataset_configuration"] = DatasetClient.prepare_dataset_payload(
|
|
368
|
+
config.dataset_configuration, True
|
|
369
|
+
)
|
|
370
|
+
|
|
371
|
+
if config.endpoint_configuration:
|
|
372
|
+
payload["endpoint_configuration"] = ModelClient.prepare_model_payload(
|
|
373
|
+
config.endpoint_configuration, True
|
|
374
|
+
)
|
|
375
|
+
|
|
376
|
+
response = self._request(
|
|
377
|
+
"POST",
|
|
378
|
+
"/redteam/v3/add-custom-task",
|
|
379
|
+
headers=headers,
|
|
380
|
+
json=payload,
|
|
381
|
+
)
|
|
382
|
+
if response.get("error"):
|
|
383
|
+
raise RedTeamClientError(f"API Error: {str(response)}")
|
|
384
|
+
return RedTeamResponse.from_dict(response)
|
|
385
|
+
else:
|
|
386
|
+
raise RedTeamClientError("Please provide a endpoint configuration")
|
|
387
|
+
|
|
388
|
+
def add_custom_task_with_saved_model_v3(
|
|
389
|
+
self,
|
|
390
|
+
config: RedTeamCustomConfigWithSavedModelV3,
|
|
391
|
+
model_saved_name: str,
|
|
392
|
+
model_version: str,
|
|
393
|
+
policy_name: str = None,
|
|
394
|
+
):
|
|
395
|
+
"""
|
|
396
|
+
Add a new red teaming custom task using a saved model with v3 attack methods format.
|
|
397
|
+
|
|
398
|
+
V3 format supports nested attack methods:
|
|
399
|
+
{
|
|
400
|
+
"test_name": {
|
|
401
|
+
"sample_percentage": 50,
|
|
402
|
+
"attack_methods": {
|
|
403
|
+
"method_category": {
|
|
404
|
+
"method_name": {
|
|
405
|
+
"params": {}
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
"""
|
|
412
|
+
if not model_saved_name:
|
|
413
|
+
raise RedTeamClientError("Please provide a model_saved_name")
|
|
414
|
+
|
|
415
|
+
if not model_version:
|
|
416
|
+
raise RedTeamClientError("Please provide a model_version. Default is 'v1'")
|
|
417
|
+
|
|
418
|
+
config = RedTeamCustomConfigWithSavedModelV3.from_dict(config)
|
|
419
|
+
test_configs = config.redteam_test_configurations.to_dict()
|
|
420
|
+
# Remove None or empty test configurations
|
|
421
|
+
test_configs = {k: v for k, v in test_configs.items() if v is not None}
|
|
422
|
+
|
|
423
|
+
payload = {
|
|
424
|
+
"test_name": config.test_name,
|
|
425
|
+
"redteam_test_configurations": test_configs,
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
# Only add frameworks if provided and not empty
|
|
429
|
+
if config.frameworks:
|
|
430
|
+
payload["frameworks"] = config.frameworks
|
|
431
|
+
print(config.__dict__)
|
|
432
|
+
if config.dataset_configuration:
|
|
433
|
+
payload["dataset_configuration"] = DatasetClient.prepare_dataset_payload(
|
|
434
|
+
config.dataset_configuration, True
|
|
435
|
+
)
|
|
436
|
+
|
|
437
|
+
headers = {
|
|
438
|
+
"X-Enkrypt-Model": model_saved_name,
|
|
439
|
+
"X-Enkrypt-Model-Version": model_version,
|
|
440
|
+
"Content-Type": "application/json",
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
if policy_name is not None:
|
|
444
|
+
headers["X-Enkrypt-Policy"] = policy_name
|
|
445
|
+
|
|
446
|
+
print("Request payload:", payload)
|
|
447
|
+
response = self._request(
|
|
448
|
+
"POST",
|
|
449
|
+
"/redteam/v3/model/add-custom-task",
|
|
450
|
+
headers=headers,
|
|
451
|
+
json=payload,
|
|
452
|
+
)
|
|
453
|
+
if response.get("error"):
|
|
454
|
+
raise RedTeamClientError(f"API Error: {str(response)}")
|
|
455
|
+
return RedTeamResponse.from_dict(response)
|
|
456
|
+
|
|
284
457
|
def status(self, task_id: str = None, test_name: str = None):
|
|
285
458
|
"""
|
|
286
459
|
Get the status of a specific red teaming task.
|
|
@@ -291,13 +464,13 @@ class RedTeamClient(BaseClient):
|
|
|
291
464
|
|
|
292
465
|
Returns:
|
|
293
466
|
dict: The task status information
|
|
294
|
-
|
|
467
|
+
|
|
295
468
|
Raises:
|
|
296
469
|
RedTeamClientError: If neither task_id nor test_name is provided, or if there's an error from the API
|
|
297
470
|
"""
|
|
298
471
|
if not task_id and not test_name:
|
|
299
472
|
raise RedTeamClientError("Either task_id or test_name must be provided")
|
|
300
|
-
|
|
473
|
+
|
|
301
474
|
headers = {}
|
|
302
475
|
if task_id:
|
|
303
476
|
headers["X-Enkrypt-Task-ID"] = task_id
|
|
@@ -352,13 +525,13 @@ class RedTeamClient(BaseClient):
|
|
|
352
525
|
|
|
353
526
|
Returns:
|
|
354
527
|
dict: The task details and status
|
|
355
|
-
|
|
528
|
+
|
|
356
529
|
Raises:
|
|
357
530
|
RedTeamClientError: If neither task_id nor test_name is provided, or if there's an error from the API
|
|
358
531
|
"""
|
|
359
532
|
if not task_id and not test_name:
|
|
360
533
|
raise RedTeamClientError("Either task_id or test_name must be provided")
|
|
361
|
-
|
|
534
|
+
|
|
362
535
|
headers = {}
|
|
363
536
|
if task_id:
|
|
364
537
|
headers["X-Enkrypt-Task-ID"] = task_id
|
|
@@ -381,26 +554,28 @@ class RedTeamClient(BaseClient):
|
|
|
381
554
|
|
|
382
555
|
Returns:
|
|
383
556
|
dict: The summary of the task results
|
|
384
|
-
|
|
557
|
+
|
|
385
558
|
Raises:
|
|
386
559
|
RedTeamClientError: If neither task_id nor test_name is provided, or if there's an error from the API
|
|
387
560
|
"""
|
|
388
561
|
if not task_id and not test_name:
|
|
389
562
|
raise RedTeamClientError("Either task_id or test_name must be provided")
|
|
390
|
-
|
|
563
|
+
|
|
391
564
|
headers = {}
|
|
392
565
|
if task_id:
|
|
393
566
|
headers["X-Enkrypt-Task-ID"] = task_id
|
|
394
567
|
if test_name:
|
|
395
568
|
headers["X-Enkrypt-Test-Name"] = test_name
|
|
396
569
|
|
|
397
|
-
response = self._request("GET", "/redteam/results/summary", headers=headers)
|
|
570
|
+
response = self._request("GET", "/redteam/v3/results/summary", headers=headers)
|
|
398
571
|
if response.get("error"):
|
|
399
572
|
raise RedTeamClientError(f"API Error: {str(response)}")
|
|
400
573
|
# print(f"Response: {response}")
|
|
401
574
|
return RedTeamResultSummary.from_dict(response)
|
|
402
|
-
|
|
403
|
-
def get_result_summary_test_type(
|
|
575
|
+
|
|
576
|
+
def get_result_summary_test_type(
|
|
577
|
+
self, task_id: str = None, test_name: str = None, test_type: str = None
|
|
578
|
+
):
|
|
404
579
|
"""
|
|
405
580
|
Get the summary of results for a specific red teaming task for a specific test type.
|
|
406
581
|
|
|
@@ -411,23 +586,23 @@ class RedTeamClient(BaseClient):
|
|
|
411
586
|
|
|
412
587
|
Returns:
|
|
413
588
|
dict: The summary of the task results for the specified test type
|
|
414
|
-
|
|
589
|
+
|
|
415
590
|
Raises:
|
|
416
591
|
RedTeamClientError: If neither task_id nor test_name is provided, or if there's an error from the API
|
|
417
592
|
"""
|
|
418
593
|
if not task_id and not test_name:
|
|
419
594
|
raise RedTeamClientError("Either task_id or test_name must be provided")
|
|
420
|
-
|
|
595
|
+
|
|
421
596
|
if not test_type:
|
|
422
597
|
raise RedTeamClientError("test_type must be provided")
|
|
423
|
-
|
|
598
|
+
|
|
424
599
|
headers = {}
|
|
425
600
|
if task_id:
|
|
426
601
|
headers["X-Enkrypt-Task-ID"] = task_id
|
|
427
602
|
if test_name:
|
|
428
603
|
headers["X-Enkrypt-Test-Name"] = test_name
|
|
429
604
|
|
|
430
|
-
url = f"/redteam/
|
|
605
|
+
url = f"/redteam/v3/results/summary/{test_type}"
|
|
431
606
|
response = self._request("GET", url, headers=headers)
|
|
432
607
|
if response.get("error"):
|
|
433
608
|
raise RedTeamClientError(f"API Error: {str(response)}")
|
|
@@ -444,25 +619,27 @@ class RedTeamClient(BaseClient):
|
|
|
444
619
|
|
|
445
620
|
Returns:
|
|
446
621
|
dict: The detailed task results
|
|
447
|
-
|
|
622
|
+
|
|
448
623
|
Raises:
|
|
449
624
|
RedTeamClientError: If neither task_id nor test_name is provided, or if there's an error from the API
|
|
450
625
|
"""
|
|
451
626
|
if not task_id and not test_name:
|
|
452
627
|
raise RedTeamClientError("Either task_id or test_name must be provided")
|
|
453
|
-
|
|
628
|
+
|
|
454
629
|
headers = {}
|
|
455
630
|
if task_id:
|
|
456
631
|
headers["X-Enkrypt-Task-ID"] = task_id
|
|
457
632
|
if test_name:
|
|
458
633
|
headers["X-Enkrypt-Test-Name"] = test_name
|
|
459
|
-
|
|
460
|
-
response = self._request("GET", "/redteam/
|
|
634
|
+
|
|
635
|
+
response = self._request("GET", "/redteam/v3/results/details", headers=headers)
|
|
461
636
|
if response.get("error"):
|
|
462
637
|
raise RedTeamClientError(f"API Error: {str(response)}")
|
|
463
638
|
return RedTeamResultDetails.from_dict(response)
|
|
464
|
-
|
|
465
|
-
def get_result_details_test_type(
|
|
639
|
+
|
|
640
|
+
def get_result_details_test_type(
|
|
641
|
+
self, task_id: str = None, test_name: str = None, test_type: str = None
|
|
642
|
+
):
|
|
466
643
|
"""
|
|
467
644
|
Get the detailed results for a specific red teaming task for a specific test type.
|
|
468
645
|
|
|
@@ -473,24 +650,23 @@ class RedTeamClient(BaseClient):
|
|
|
473
650
|
|
|
474
651
|
Returns:
|
|
475
652
|
dict: The detailed task results
|
|
476
|
-
|
|
653
|
+
|
|
477
654
|
Raises:
|
|
478
655
|
RedTeamClientError: If neither task_id nor test_name is provided, or if there's an error from the API
|
|
479
656
|
"""
|
|
480
657
|
if not task_id and not test_name:
|
|
481
658
|
raise RedTeamClientError("Either task_id or test_name must be provided")
|
|
482
|
-
|
|
659
|
+
|
|
483
660
|
if not test_type:
|
|
484
661
|
raise RedTeamClientError("test_type must be provided")
|
|
485
|
-
|
|
662
|
+
|
|
486
663
|
headers = {}
|
|
487
664
|
if task_id:
|
|
488
665
|
headers["X-Enkrypt-Task-ID"] = task_id
|
|
489
666
|
if test_name:
|
|
490
667
|
headers["X-Enkrypt-Test-Name"] = test_name
|
|
491
|
-
|
|
492
668
|
|
|
493
|
-
url = f"/redteam/
|
|
669
|
+
url = f"/redteam/v3/results/details/{test_type}"
|
|
494
670
|
response = self._request("GET", url, headers=headers)
|
|
495
671
|
if response.get("error"):
|
|
496
672
|
raise RedTeamClientError(f"API Error: {str(response)}")
|
|
@@ -515,26 +691,34 @@ class RedTeamClient(BaseClient):
|
|
|
515
691
|
raise RedTeamClientError(f"API Error: {str(response)}")
|
|
516
692
|
return RedTeamTaskList.from_dict(response)
|
|
517
693
|
|
|
518
|
-
def risk_mitigation_guardrails_policy(
|
|
694
|
+
def risk_mitigation_guardrails_policy(
|
|
695
|
+
self, config: RedTeamRiskMitigationGuardrailsPolicyConfig
|
|
696
|
+
):
|
|
519
697
|
"""
|
|
520
698
|
Get the guardrails policy generated for risk mitigation.
|
|
521
699
|
"""
|
|
522
700
|
config = RedTeamRiskMitigationGuardrailsPolicyConfig.from_dict(config)
|
|
523
701
|
payload = config.to_dict()
|
|
524
|
-
|
|
525
|
-
response = self._request(
|
|
702
|
+
|
|
703
|
+
response = self._request(
|
|
704
|
+
"POST", "/redteam/risk-mitigation/guardrails-policy", json=payload
|
|
705
|
+
)
|
|
526
706
|
if isinstance(response, dict) and response.get("error"):
|
|
527
707
|
raise RedTeamClientError(f"API Error: {str(response)}")
|
|
528
708
|
return RedTeamRiskMitigationGuardrailsPolicyResponse.from_dict(response)
|
|
529
709
|
|
|
530
|
-
def risk_mitigation_system_prompt(
|
|
710
|
+
def risk_mitigation_system_prompt(
|
|
711
|
+
self, config: RedTeamRiskMitigationSystemPromptConfig
|
|
712
|
+
):
|
|
531
713
|
"""
|
|
532
714
|
Get the system prompt generated for risk mitigation.
|
|
533
715
|
"""
|
|
534
716
|
config = RedTeamRiskMitigationSystemPromptConfig.from_dict(config)
|
|
535
717
|
payload = config.to_dict()
|
|
536
|
-
|
|
537
|
-
response = self._request(
|
|
718
|
+
|
|
719
|
+
response = self._request(
|
|
720
|
+
"POST", "/redteam/risk-mitigation/system-prompt", json=payload
|
|
721
|
+
)
|
|
538
722
|
if isinstance(response, dict) and response.get("error"):
|
|
539
723
|
raise RedTeamClientError(f"API Error: {str(response)}")
|
|
540
724
|
return RedTeamRiskMitigationSystemPromptResponse.from_dict(response)
|
|
@@ -542,20 +726,18 @@ class RedTeamClient(BaseClient):
|
|
|
542
726
|
def get_findings(self, redteam_summary):
|
|
543
727
|
"""
|
|
544
728
|
Get findings and insights based on red team summary data.
|
|
545
|
-
|
|
729
|
+
|
|
546
730
|
Parameters:
|
|
547
731
|
- redteam_summary (dict or ResultSummary): Red team test summary data
|
|
548
|
-
|
|
732
|
+
|
|
549
733
|
Returns:
|
|
550
734
|
- RedTeamFindingsResponse: Response from the API containing findings
|
|
551
735
|
"""
|
|
552
736
|
# Allow passing in either a dict or a ResultSummary instance
|
|
553
737
|
if hasattr(redteam_summary, "to_dict"):
|
|
554
738
|
redteam_summary = redteam_summary.to_dict()
|
|
555
|
-
|
|
556
|
-
payload = {
|
|
557
|
-
"redteam_summary": redteam_summary
|
|
558
|
-
}
|
|
739
|
+
|
|
740
|
+
payload = {"redteam_summary": redteam_summary}
|
|
559
741
|
|
|
560
742
|
try:
|
|
561
743
|
response = self._request("POST", "/redteam/findings", json=payload)
|
|
@@ -564,4 +746,34 @@ class RedTeamClient(BaseClient):
|
|
|
564
746
|
return RedTeamFindingsResponse.from_dict(response)
|
|
565
747
|
except Exception as e:
|
|
566
748
|
raise RedTeamClientError(str(e))
|
|
567
|
-
|
|
749
|
+
|
|
750
|
+
def get_download_link(self, task_id: str = None, test_name: str = None):
|
|
751
|
+
"""
|
|
752
|
+
Get a download link for red team test results.
|
|
753
|
+
|
|
754
|
+
Args:
|
|
755
|
+
task_id (str, optional): The ID of the task to get download link for
|
|
756
|
+
test_name (str, optional): The name of the test to get download link for
|
|
757
|
+
|
|
758
|
+
Returns:
|
|
759
|
+
RedTeamDownloadLinkResponse: Response containing download link and expiry information
|
|
760
|
+
|
|
761
|
+
Raises:
|
|
762
|
+
RedTeamClientError: If neither task_id nor test_name is provided, or if there's an error from the API
|
|
763
|
+
"""
|
|
764
|
+
if not task_id and not test_name:
|
|
765
|
+
raise RedTeamClientError("Either task_id or test_name must be provided")
|
|
766
|
+
|
|
767
|
+
headers = {}
|
|
768
|
+
if task_id:
|
|
769
|
+
headers["X-Enkrypt-Task-ID"] = task_id
|
|
770
|
+
if test_name:
|
|
771
|
+
headers["X-Enkrypt-Test-Name"] = test_name
|
|
772
|
+
|
|
773
|
+
try:
|
|
774
|
+
response = self._request("GET", "/redteam/download-link", headers=headers)
|
|
775
|
+
if response.get("error"):
|
|
776
|
+
raise RedTeamClientError(f"API Error: {str(response)}")
|
|
777
|
+
return RedTeamDownloadLinkResponse.from_dict(response)
|
|
778
|
+
except Exception as e:
|
|
779
|
+
raise RedTeamClientError(str(e))
|