enkryptai-sdk 1.0.6__py3-none-any.whl → 1.0.8__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/ai_proxy.py +2 -2
- enkryptai_sdk/datasets.py +34 -15
- enkryptai_sdk/deployments.py +5 -5
- enkryptai_sdk/dto/__init__.py +2 -0
- enkryptai_sdk/dto/datasets.py +9 -5
- enkryptai_sdk/dto/models.py +8 -8
- enkryptai_sdk/dto/red_team.py +84 -1
- enkryptai_sdk/guardrails.py +16 -16
- enkryptai_sdk/models.py +40 -25
- enkryptai_sdk/red_team.py +129 -14
- {enkryptai_sdk-1.0.6.dist-info → enkryptai_sdk-1.0.8.dist-info}/METADATA +116 -1
- enkryptai_sdk-1.0.8.dist-info/RECORD +25 -0
- enkryptai_sdk-1.0.6.dist-info/RECORD +0 -25
- {enkryptai_sdk-1.0.6.dist-info → enkryptai_sdk-1.0.8.dist-info}/WHEEL +0 -0
- {enkryptai_sdk-1.0.6.dist-info → enkryptai_sdk-1.0.8.dist-info}/licenses/LICENSE +0 -0
- {enkryptai_sdk-1.0.6.dist-info → enkryptai_sdk-1.0.8.dist-info}/top_level.txt +0 -0
enkryptai_sdk/ai_proxy.py
CHANGED
|
@@ -60,7 +60,7 @@ class AIProxyClient(BaseClient):
|
|
|
60
60
|
# # As json.loads is not working with literal string representation of dict
|
|
61
61
|
# parsed_error = json.loads(error_message.replace("'", '"'))
|
|
62
62
|
# # Convert Python string representation to proper dict
|
|
63
|
-
parsed_error = ast.literal_eval(response
|
|
63
|
+
parsed_error = ast.literal_eval(f"API Error: {str(response)}")
|
|
64
64
|
# # Preserve both error and enkrypt_policy_detections fields
|
|
65
65
|
response["error"] = parsed_error.get("error", parsed_error)
|
|
66
66
|
if "enkrypt_policy_detections" in parsed_error:
|
|
@@ -84,6 +84,6 @@ class AIProxyClient(BaseClient):
|
|
|
84
84
|
# Fallback to direct error if error object can't be parsed
|
|
85
85
|
# print("Failed to parse error response: ", response)
|
|
86
86
|
return ChatCompletionDirectErrorResponse.from_dict(response)
|
|
87
|
-
raise AIProxyClientError(response
|
|
87
|
+
raise AIProxyClientError(f"API Error: {str(response)}")
|
|
88
88
|
|
|
89
89
|
return ChatCompletionResponse.from_dict(response)
|
enkryptai_sdk/datasets.py
CHANGED
|
@@ -19,6 +19,32 @@ class DatasetClient(BaseClient):
|
|
|
19
19
|
def __init__(self, api_key: str, base_url: str = "https://api.enkryptai.com"):
|
|
20
20
|
super().__init__(api_key, base_url)
|
|
21
21
|
|
|
22
|
+
@staticmethod
|
|
23
|
+
def prepare_dataset_payload(config: DatasetConfig | dict, is_custom: bool = False) -> dict:
|
|
24
|
+
"""
|
|
25
|
+
Prepare the payload for dataset operations from a config object.
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
config (Union[DatasetConfig, dict]): Configuration object or dictionary containing dataset details
|
|
29
|
+
|
|
30
|
+
Returns:
|
|
31
|
+
dict: Processed payload ready for API submission
|
|
32
|
+
"""
|
|
33
|
+
if isinstance(config, dict):
|
|
34
|
+
config = DatasetConfig.from_dict(config)
|
|
35
|
+
|
|
36
|
+
payload = config.to_dict()
|
|
37
|
+
|
|
38
|
+
if not is_custom:
|
|
39
|
+
# Remove empty tools configuration
|
|
40
|
+
if (payload.get("tools") is None or
|
|
41
|
+
payload["tools"] == [] or
|
|
42
|
+
payload["tools"] == [{}] or
|
|
43
|
+
payload["tools"] == [{"name": "", "description": ""}]):
|
|
44
|
+
del payload["tools"]
|
|
45
|
+
|
|
46
|
+
return payload
|
|
47
|
+
|
|
22
48
|
def add_dataset(self, config: DatasetConfig):
|
|
23
49
|
"""
|
|
24
50
|
Add a new dataset to the system.
|
|
@@ -34,14 +60,7 @@ class DatasetClient(BaseClient):
|
|
|
34
60
|
if isinstance(config, dict):
|
|
35
61
|
config = DatasetConfig.from_dict(config)
|
|
36
62
|
|
|
37
|
-
payload =
|
|
38
|
-
|
|
39
|
-
# If payload["tools"] is None or is an empty list [] or [{}], remove it from the payload
|
|
40
|
-
if (payload.get("tools") is None or
|
|
41
|
-
payload["tools"] == [] or
|
|
42
|
-
payload["tools"] == [{}] or
|
|
43
|
-
payload["tools"] == [{"name": "", "description": ""}]):
|
|
44
|
-
del payload["tools"]
|
|
63
|
+
payload = self.prepare_dataset_payload(config)
|
|
45
64
|
|
|
46
65
|
# Print payload
|
|
47
66
|
# print(f"\nAdd Dataset Payload: {payload}")
|
|
@@ -54,7 +73,7 @@ class DatasetClient(BaseClient):
|
|
|
54
73
|
# print(f"\nAdd Dataset Response: {response}")
|
|
55
74
|
|
|
56
75
|
if response.get("error"):
|
|
57
|
-
raise DatasetClientError(response
|
|
76
|
+
raise DatasetClientError(f"API Error: {str(response)}")
|
|
58
77
|
return DatasetAddTaskResponse.from_dict(response)
|
|
59
78
|
|
|
60
79
|
def get_dataset_task_status(self, dataset_name: str):
|
|
@@ -70,7 +89,7 @@ class DatasetClient(BaseClient):
|
|
|
70
89
|
headers = {"X-Enkrypt-Dataset": dataset_name}
|
|
71
90
|
response = self._request("GET", "/datasets/task-status", headers=headers)
|
|
72
91
|
if response.get("error"):
|
|
73
|
-
raise DatasetClientError(response
|
|
92
|
+
raise DatasetClientError(f"API Error: {str(response)}")
|
|
74
93
|
response["dataset_name"] = dataset_name
|
|
75
94
|
return DatasetTaskStatus.from_dict(response)
|
|
76
95
|
|
|
@@ -87,7 +106,7 @@ class DatasetClient(BaseClient):
|
|
|
87
106
|
headers = {"X-Enkrypt-Dataset": dataset_name}
|
|
88
107
|
response = self._request("GET", "/datasets/get-task", headers=headers)
|
|
89
108
|
if response.get("error"):
|
|
90
|
-
raise DatasetClientError(response
|
|
109
|
+
raise DatasetClientError(f"API Error: {str(response)}")
|
|
91
110
|
response["dataset_name"] = dataset_name
|
|
92
111
|
return DatasetTask.from_dict(response)
|
|
93
112
|
|
|
@@ -104,7 +123,7 @@ class DatasetClient(BaseClient):
|
|
|
104
123
|
headers = {"X-Enkrypt-Dataset": dataset_name}
|
|
105
124
|
response = self._request("GET", "/datasets/get-datacard", headers=headers)
|
|
106
125
|
if response.get("error"):
|
|
107
|
-
raise DatasetClientError(response
|
|
126
|
+
raise DatasetClientError(f"API Error: {str(response)}")
|
|
108
127
|
response["dataset_name"] = dataset_name
|
|
109
128
|
return DatasetCard.from_dict(response)
|
|
110
129
|
|
|
@@ -121,7 +140,7 @@ class DatasetClient(BaseClient):
|
|
|
121
140
|
headers = {"X-Enkrypt-Dataset": dataset_name}
|
|
122
141
|
response = self._request("GET", "/datasets/get-dataset", headers=headers)
|
|
123
142
|
if response.get("error"):
|
|
124
|
-
raise DatasetClientError(response
|
|
143
|
+
raise DatasetClientError(f"API Error: {str(response)}")
|
|
125
144
|
response["dataset_name"] = dataset_name
|
|
126
145
|
return DatasetResponse.from_dict(response)
|
|
127
146
|
|
|
@@ -138,7 +157,7 @@ class DatasetClient(BaseClient):
|
|
|
138
157
|
headers = {"X-Enkrypt-Dataset": dataset_name}
|
|
139
158
|
response = self._request("GET", "/datasets/get-summary", headers=headers)
|
|
140
159
|
if response.get("error"):
|
|
141
|
-
raise DatasetClientError(response
|
|
160
|
+
raise DatasetClientError(f"API Error: {str(response)}")
|
|
142
161
|
response["dataset_name"] = dataset_name
|
|
143
162
|
return DatasetSummary.from_dict(response)
|
|
144
163
|
|
|
@@ -158,5 +177,5 @@ class DatasetClient(BaseClient):
|
|
|
158
177
|
url += f"?status={status}"
|
|
159
178
|
response = self._request("GET", url)
|
|
160
179
|
if response.get("error"):
|
|
161
|
-
raise DatasetClientError(response
|
|
180
|
+
raise DatasetClientError(f"API Error: {str(response)}")
|
|
162
181
|
return DatasetCollection.from_dict(response)
|
enkryptai_sdk/deployments.py
CHANGED
|
@@ -46,7 +46,7 @@ class DeploymentClient(BaseClient):
|
|
|
46
46
|
"POST", "/deployments/add-deployment", headers=headers, json=payload
|
|
47
47
|
)
|
|
48
48
|
if response.get("error"):
|
|
49
|
-
raise DeploymentClientError(response
|
|
49
|
+
raise DeploymentClientError(f"API Error: {str(response)}")
|
|
50
50
|
return DeploymentAddTaskResponse.from_dict(response)
|
|
51
51
|
|
|
52
52
|
def get_deployment(self, deployment_name: str, refresh_cache: bool = False):
|
|
@@ -64,7 +64,7 @@ class DeploymentClient(BaseClient):
|
|
|
64
64
|
headers["X-Enkrypt-Refresh-Cache"] = "true" if refresh_cache else "false"
|
|
65
65
|
response = self._request("GET", "/deployments/get-deployment", headers=headers)
|
|
66
66
|
if response.get("error"):
|
|
67
|
-
raise DeploymentClientError(response
|
|
67
|
+
raise DeploymentClientError(f"API Error: {str(response)}")
|
|
68
68
|
return GetDeploymentResponse.from_dict(response)
|
|
69
69
|
|
|
70
70
|
def modify_deployment(self, deployment_name: str, config: DeploymentInput):
|
|
@@ -88,7 +88,7 @@ class DeploymentClient(BaseClient):
|
|
|
88
88
|
"PATCH", "/deployments/modify-deployment", headers=headers, json=payload
|
|
89
89
|
)
|
|
90
90
|
if response.get("error"):
|
|
91
|
-
raise DeploymentClientError(response
|
|
91
|
+
raise DeploymentClientError(f"API Error: {str(response)}")
|
|
92
92
|
return ModifyDeploymentResponse.from_dict(response)
|
|
93
93
|
|
|
94
94
|
def delete_deployment(self, deployment_name: str):
|
|
@@ -104,7 +104,7 @@ class DeploymentClient(BaseClient):
|
|
|
104
104
|
headers = {"X-Enkrypt-Deployment": deployment_name}
|
|
105
105
|
response = self._request("DELETE", "/deployments/delete-deployment", headers=headers)
|
|
106
106
|
if response.get("error"):
|
|
107
|
-
raise DeploymentClientError(response
|
|
107
|
+
raise DeploymentClientError(f"API Error: {str(response)}")
|
|
108
108
|
return DeleteDeploymentResponse.from_dict(response)
|
|
109
109
|
|
|
110
110
|
def list_deployments(self):
|
|
@@ -117,5 +117,5 @@ class DeploymentClient(BaseClient):
|
|
|
117
117
|
|
|
118
118
|
response = self._request("GET", "/deployments/list-deployments")
|
|
119
119
|
if response.get("error"):
|
|
120
|
-
raise DeploymentClientError(response
|
|
120
|
+
raise DeploymentClientError(f"API Error: {str(response)}")
|
|
121
121
|
return DeploymentCollection.from_dict(response)
|
enkryptai_sdk/dto/__init__.py
CHANGED
|
@@ -22,6 +22,8 @@ __all__ = [
|
|
|
22
22
|
"Metadata",
|
|
23
23
|
"DEFAULT_REDTEAM_CONFIG",
|
|
24
24
|
"DEFAULT_REDTEAM_CONFIG_WITH_SAVED_MODEL",
|
|
25
|
+
"DEFAULT_CUSTOM_REDTEAM_CONFIG",
|
|
26
|
+
"DEFAULT_CUSTOM_REDTEAM_CONFIG_WITH_SAVED_MODEL",
|
|
25
27
|
"ADVANCED_REDTEAM_TESTS",
|
|
26
28
|
"DETAIL_MODEL_CONFIG",
|
|
27
29
|
"DatasetConfig",
|
enkryptai_sdk/dto/datasets.py
CHANGED
|
@@ -21,17 +21,20 @@ class Tool(BaseDTO):
|
|
|
21
21
|
"description": self.description
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
+
|
|
24
25
|
@dataclass
|
|
25
26
|
class DatasetConfig(BaseDTO):
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
policy_description: str =
|
|
29
|
-
|
|
30
|
-
|
|
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
|
|
31
33
|
max_prompts: int = 100
|
|
32
34
|
scenarios: int = 2
|
|
33
35
|
categories: int = 2
|
|
34
36
|
depth: int = 2
|
|
37
|
+
_extra_fields: Dict[str, Any] = field(default_factory=dict)
|
|
35
38
|
|
|
36
39
|
|
|
37
40
|
@dataclass
|
|
@@ -51,6 +54,7 @@ class DatasetDataPoint(BaseDTO):
|
|
|
51
54
|
category: str
|
|
52
55
|
prompt: str
|
|
53
56
|
source: str
|
|
57
|
+
_extra_fields: Dict[str, Any] = field(default_factory=dict)
|
|
54
58
|
|
|
55
59
|
|
|
56
60
|
@dataclass
|
enkryptai_sdk/dto/models.py
CHANGED
|
@@ -142,8 +142,8 @@ class CustomHeader(BaseDTO):
|
|
|
142
142
|
|
|
143
143
|
@dataclass
|
|
144
144
|
class ModelConfigDetails(BaseDTO):
|
|
145
|
-
model_id: str =
|
|
146
|
-
model_source: str =
|
|
145
|
+
model_id: str = None
|
|
146
|
+
model_source: str = None
|
|
147
147
|
# model_provider: str = "openai"
|
|
148
148
|
model_provider: ModelProviders = ModelProviders.OPENAI
|
|
149
149
|
model_api_value: str = ""
|
|
@@ -259,14 +259,14 @@ class ModelConfigDetails(BaseDTO):
|
|
|
259
259
|
|
|
260
260
|
@dataclass
|
|
261
261
|
class ModelConfig(BaseDTO):
|
|
262
|
-
created_at: str =
|
|
263
|
-
updated_at: str =
|
|
264
|
-
model_id: str =
|
|
265
|
-
model_saved_name: str =
|
|
266
|
-
model_version: str =
|
|
262
|
+
created_at: str = None
|
|
263
|
+
updated_at: str = None
|
|
264
|
+
model_id: str = None
|
|
265
|
+
model_saved_name: str = None
|
|
266
|
+
model_version: str = None
|
|
267
267
|
testing_for: str = "foundationModels"
|
|
268
268
|
# modality: Modality = Modality.TEXT
|
|
269
|
-
project_name: str =
|
|
269
|
+
project_name: str = None
|
|
270
270
|
model_name: Optional[str] = "gpt-4o-mini"
|
|
271
271
|
certifications: List[str] = field(default_factory=list)
|
|
272
272
|
model_config: ModelConfigDetails = field(default_factory=ModelConfigDetails)
|
enkryptai_sdk/dto/red_team.py
CHANGED
|
@@ -3,6 +3,8 @@ from enum import Enum
|
|
|
3
3
|
from .base import BaseDTO
|
|
4
4
|
from typing import Dict, List, Optional, Any
|
|
5
5
|
from dataclasses import dataclass, field, asdict
|
|
6
|
+
from .datasets import DatasetConfig
|
|
7
|
+
from .models import ModelConfig
|
|
6
8
|
|
|
7
9
|
|
|
8
10
|
@dataclass
|
|
@@ -24,6 +26,7 @@ class RedteamHealthResponse(BaseDTO):
|
|
|
24
26
|
|
|
25
27
|
@dataclass
|
|
26
28
|
class RedTeamResponse(BaseDTO):
|
|
29
|
+
status: Optional[str] = None
|
|
27
30
|
task_id: Optional[str] = None
|
|
28
31
|
message: Optional[str] = None
|
|
29
32
|
data: Optional[Dict[str, Any]] = None
|
|
@@ -300,7 +303,7 @@ class RedTeamTestConfigurations(BaseDTO):
|
|
|
300
303
|
adv_info_test: TestConfig = field(default=None)
|
|
301
304
|
adv_bias_test: TestConfig = field(default=None)
|
|
302
305
|
adv_command_test: TestConfig = field(default=None)
|
|
303
|
-
|
|
306
|
+
custom_test: TestConfig = field(default=None)
|
|
304
307
|
_extra_fields: Dict[str, Any] = field(default_factory=dict)
|
|
305
308
|
|
|
306
309
|
@classmethod
|
|
@@ -482,6 +485,83 @@ class RedTeamConfigWithSavedModel(BaseDTO):
|
|
|
482
485
|
)
|
|
483
486
|
|
|
484
487
|
|
|
488
|
+
@dataclass
|
|
489
|
+
class RedTeamCustomConfig(BaseDTO):
|
|
490
|
+
test_name: str = "Test Name"
|
|
491
|
+
|
|
492
|
+
redteam_test_configurations: RedTeamTestConfigurations = field(
|
|
493
|
+
default_factory=RedTeamTestConfigurations
|
|
494
|
+
)
|
|
495
|
+
dataset_configuration: DatasetConfig = field(
|
|
496
|
+
default_factory=DatasetConfig
|
|
497
|
+
)
|
|
498
|
+
endpoint_configuration: ModelConfig = field(
|
|
499
|
+
default_factory=ModelConfig
|
|
500
|
+
)
|
|
501
|
+
|
|
502
|
+
_extra_fields: Dict[str, Any] = field(default_factory=dict)
|
|
503
|
+
|
|
504
|
+
def to_dict(self) -> dict:
|
|
505
|
+
d = asdict(self)
|
|
506
|
+
d["redteam_test_configurations"] = self.redteam_test_configurations.to_dict()
|
|
507
|
+
d["dataset_configuration"] = self.dataset_configuration.to_dict()
|
|
508
|
+
d["endpoint_configuration"] = self.endpoint_configuration.to_dict()
|
|
509
|
+
return d
|
|
510
|
+
|
|
511
|
+
@classmethod
|
|
512
|
+
def from_dict(cls, data: dict):
|
|
513
|
+
data = data.copy()
|
|
514
|
+
test_configs = RedTeamTestConfigurations.from_dict(
|
|
515
|
+
data.pop("redteam_test_configurations", {})
|
|
516
|
+
)
|
|
517
|
+
dataset_config = DatasetConfig.from_dict(
|
|
518
|
+
data.pop("dataset_configuration", {})
|
|
519
|
+
)
|
|
520
|
+
endpoint_config = ModelConfig.from_dict(
|
|
521
|
+
data.pop("endpoint_configuration", {})
|
|
522
|
+
)
|
|
523
|
+
return cls(
|
|
524
|
+
**data,
|
|
525
|
+
redteam_test_configurations=test_configs,
|
|
526
|
+
dataset_configuration=dataset_config,
|
|
527
|
+
endpoint_configuration=endpoint_config,
|
|
528
|
+
)
|
|
529
|
+
|
|
530
|
+
@dataclass
|
|
531
|
+
class RedTeamCustomConfigWithSavedModel(BaseDTO):
|
|
532
|
+
test_name: str = "Test Name"
|
|
533
|
+
|
|
534
|
+
redteam_test_configurations: RedTeamTestConfigurations = field(
|
|
535
|
+
default_factory=RedTeamTestConfigurations
|
|
536
|
+
)
|
|
537
|
+
dataset_configuration: DatasetConfig = field(
|
|
538
|
+
default_factory=DatasetConfig
|
|
539
|
+
)
|
|
540
|
+
|
|
541
|
+
_extra_fields: Dict[str, Any] = field(default_factory=dict)
|
|
542
|
+
|
|
543
|
+
def to_dict(self) -> dict:
|
|
544
|
+
d = asdict(self)
|
|
545
|
+
d["redteam_test_configurations"] = self.redteam_test_configurations.to_dict()
|
|
546
|
+
d["dataset_configuration"] = self.dataset_configuration.to_dict()
|
|
547
|
+
return d
|
|
548
|
+
|
|
549
|
+
@classmethod
|
|
550
|
+
def from_dict(cls, data: dict):
|
|
551
|
+
data = data.copy()
|
|
552
|
+
test_configs = RedTeamTestConfigurations.from_dict(
|
|
553
|
+
data.pop("redteam_test_configurations", {})
|
|
554
|
+
)
|
|
555
|
+
dataset_config = DatasetConfig.from_dict(
|
|
556
|
+
data.pop("dataset_configuration", {})
|
|
557
|
+
)
|
|
558
|
+
return cls(
|
|
559
|
+
**data,
|
|
560
|
+
redteam_test_configurations=test_configs,
|
|
561
|
+
dataset_configuration=dataset_config,
|
|
562
|
+
)
|
|
563
|
+
|
|
564
|
+
|
|
485
565
|
@dataclass
|
|
486
566
|
class RedTeamTaskList(BaseDTO):
|
|
487
567
|
tasks: List[RedTeamTaskDetails] = field(default_factory=list)
|
|
@@ -494,3 +574,6 @@ class RedTeamTaskList(BaseDTO):
|
|
|
494
574
|
# Default configurations
|
|
495
575
|
DEFAULT_REDTEAM_CONFIG = RedTeamConfig()
|
|
496
576
|
DEFAULT_REDTEAM_CONFIG_WITH_SAVED_MODEL = RedTeamConfigWithSavedModel()
|
|
577
|
+
|
|
578
|
+
DEFAULT_CUSTOM_REDTEAM_CONFIG = RedTeamCustomConfig()
|
|
579
|
+
DEFAULT_CUSTOM_REDTEAM_CONFIG_WITH_SAVED_MODEL = RedTeamCustomConfigWithSavedModel()
|
enkryptai_sdk/guardrails.py
CHANGED
|
@@ -92,7 +92,7 @@ class GuardrailsClient(BaseClient):
|
|
|
92
92
|
try:
|
|
93
93
|
response = self._request("GET", "/guardrails/health")
|
|
94
94
|
if response.get("error"):
|
|
95
|
-
raise GuardrailsClientError(response
|
|
95
|
+
raise GuardrailsClientError(f"API Error: {str(response)}")
|
|
96
96
|
return GuardrailsHealthResponse.from_dict(response)
|
|
97
97
|
except Exception as e:
|
|
98
98
|
raise GuardrailsClientError(str(e))
|
|
@@ -104,7 +104,7 @@ class GuardrailsClient(BaseClient):
|
|
|
104
104
|
try:
|
|
105
105
|
response = self._request("GET", "/guardrails/status")
|
|
106
106
|
if response.get("error"):
|
|
107
|
-
raise GuardrailsClientError(response
|
|
107
|
+
raise GuardrailsClientError(f"API Error: {str(response)}")
|
|
108
108
|
return GuardrailsHealthResponse.from_dict(response)
|
|
109
109
|
except Exception as e:
|
|
110
110
|
raise GuardrailsClientError(str(e))
|
|
@@ -116,7 +116,7 @@ class GuardrailsClient(BaseClient):
|
|
|
116
116
|
try:
|
|
117
117
|
response = self._request("GET", "/guardrails/models")
|
|
118
118
|
if response.get("error"):
|
|
119
|
-
raise GuardrailsClientError(response
|
|
119
|
+
raise GuardrailsClientError(f"API Error: {str(response)}")
|
|
120
120
|
return GuardrailsModelsResponse.from_dict(response)
|
|
121
121
|
except Exception as e:
|
|
122
122
|
raise GuardrailsClientError(str(e))
|
|
@@ -152,7 +152,7 @@ class GuardrailsClient(BaseClient):
|
|
|
152
152
|
try:
|
|
153
153
|
response = self._request("POST", "/guardrails/detect", json=payload)
|
|
154
154
|
if response.get("error"):
|
|
155
|
-
raise GuardrailsClientError(response
|
|
155
|
+
raise GuardrailsClientError(f"API Error: {str(response)}")
|
|
156
156
|
return GuardrailsDetectResponse.from_dict(response)
|
|
157
157
|
except Exception as e:
|
|
158
158
|
raise GuardrailsClientError(str(e))
|
|
@@ -188,7 +188,7 @@ class GuardrailsClient(BaseClient):
|
|
|
188
188
|
try:
|
|
189
189
|
response = self._request("POST", "/guardrails/batch/detect", json=payload)
|
|
190
190
|
if isinstance(response, dict) and response.get("error"):
|
|
191
|
-
raise GuardrailsClientError(response
|
|
191
|
+
raise GuardrailsClientError(f"API Error: {str(response)}")
|
|
192
192
|
return GuardrailsBatchDetectResponse.from_dict(response)
|
|
193
193
|
except Exception as e:
|
|
194
194
|
raise GuardrailsClientError(str(e))
|
|
@@ -207,7 +207,7 @@ class GuardrailsClient(BaseClient):
|
|
|
207
207
|
try:
|
|
208
208
|
response = self._request("POST", "/guardrails/pii", json=payload)
|
|
209
209
|
if response.get("error"):
|
|
210
|
-
raise GuardrailsClientError(response
|
|
210
|
+
raise GuardrailsClientError(f"API Error: {str(response)}")
|
|
211
211
|
return GuardrailsPIIResponse.from_dict(response)
|
|
212
212
|
except Exception as e:
|
|
213
213
|
raise GuardrailsClientError(str(e))
|
|
@@ -225,7 +225,7 @@ class GuardrailsClient(BaseClient):
|
|
|
225
225
|
try:
|
|
226
226
|
response = self._request("POST", "/guardrails/hallucination", json=payload)
|
|
227
227
|
if response.get("error"):
|
|
228
|
-
raise GuardrailsClientError(response
|
|
228
|
+
raise GuardrailsClientError(f"API Error: {str(response)}")
|
|
229
229
|
return GuardrailsHallucinationResponse.from_dict(response)
|
|
230
230
|
except Exception as e:
|
|
231
231
|
raise GuardrailsClientError(str(e))
|
|
@@ -242,7 +242,7 @@ class GuardrailsClient(BaseClient):
|
|
|
242
242
|
try:
|
|
243
243
|
response = self._request("POST", "/guardrails/adherence", json=payload)
|
|
244
244
|
if response.get("error"):
|
|
245
|
-
raise GuardrailsClientError(response
|
|
245
|
+
raise GuardrailsClientError(f"API Error: {str(response)}")
|
|
246
246
|
return GuardrailsAdherenceResponse.from_dict(response)
|
|
247
247
|
except Exception as e:
|
|
248
248
|
raise GuardrailsClientError(str(e))
|
|
@@ -259,7 +259,7 @@ class GuardrailsClient(BaseClient):
|
|
|
259
259
|
try:
|
|
260
260
|
response = self._request("POST", "/guardrails/relevancy", json=payload)
|
|
261
261
|
if response.get("error"):
|
|
262
|
-
raise GuardrailsClientError(response
|
|
262
|
+
raise GuardrailsClientError(f"API Error: {str(response)}")
|
|
263
263
|
return GuardrailsRelevancyResponse.from_dict(response)
|
|
264
264
|
except Exception as e:
|
|
265
265
|
raise GuardrailsClientError(str(e))
|
|
@@ -293,7 +293,7 @@ class GuardrailsClient(BaseClient):
|
|
|
293
293
|
try:
|
|
294
294
|
response = self._request("POST", "/guardrails/add-policy", json=payload)
|
|
295
295
|
if response.get("error"):
|
|
296
|
-
raise GuardrailsClientError(response
|
|
296
|
+
raise GuardrailsClientError(f"API Error: {str(response)}")
|
|
297
297
|
return GuardrailsaPolicyResponse.from_dict(response)
|
|
298
298
|
except Exception as e:
|
|
299
299
|
raise GuardrailsClientError(str(e))
|
|
@@ -307,7 +307,7 @@ class GuardrailsClient(BaseClient):
|
|
|
307
307
|
try:
|
|
308
308
|
response = self._request("GET", "/guardrails/get-policy", headers=headers)
|
|
309
309
|
if response.get("error"):
|
|
310
|
-
raise GuardrailsClientError(response
|
|
310
|
+
raise GuardrailsClientError(f"API Error: {str(response)}")
|
|
311
311
|
return GuardrailsPolicyData.from_dict(response)
|
|
312
312
|
except Exception as e:
|
|
313
313
|
raise GuardrailsClientError(str(e))
|
|
@@ -335,7 +335,7 @@ class GuardrailsClient(BaseClient):
|
|
|
335
335
|
try:
|
|
336
336
|
response = self._request("PATCH", "/guardrails/modify-policy", headers=headers, json=payload)
|
|
337
337
|
if response.get("error"):
|
|
338
|
-
raise GuardrailsClientError(response
|
|
338
|
+
raise GuardrailsClientError(f"API Error: {str(response)}")
|
|
339
339
|
return GuardrailsaPolicyResponse.from_dict(response)
|
|
340
340
|
except Exception as e:
|
|
341
341
|
raise GuardrailsClientError(str(e))
|
|
@@ -349,7 +349,7 @@ class GuardrailsClient(BaseClient):
|
|
|
349
349
|
try:
|
|
350
350
|
response = self._request("DELETE", "/guardrails/delete-policy", headers=headers)
|
|
351
351
|
if response.get("error"):
|
|
352
|
-
raise GuardrailsClientError(response
|
|
352
|
+
raise GuardrailsClientError(f"API Error: {str(response)}")
|
|
353
353
|
return GuardrailsDeletePolicyResponse.from_dict(response)
|
|
354
354
|
except Exception as e:
|
|
355
355
|
raise GuardrailsClientError(str(e))
|
|
@@ -364,7 +364,7 @@ class GuardrailsClient(BaseClient):
|
|
|
364
364
|
try:
|
|
365
365
|
response = self._request("POST", "/guardrails/policy/detect", headers=headers, json=payload)
|
|
366
366
|
if response.get("error"):
|
|
367
|
-
raise GuardrailsClientError(response
|
|
367
|
+
raise GuardrailsClientError(f"API Error: {str(response)}")
|
|
368
368
|
return GuardrailsDetectResponse.from_dict(response)
|
|
369
369
|
except Exception as e:
|
|
370
370
|
raise GuardrailsClientError(str(e))
|
|
@@ -376,8 +376,8 @@ class GuardrailsClient(BaseClient):
|
|
|
376
376
|
|
|
377
377
|
try:
|
|
378
378
|
response = self._request("GET", "/guardrails/list-policies")
|
|
379
|
-
if response.get("error"):
|
|
380
|
-
raise GuardrailsClientError(response
|
|
379
|
+
if isinstance(response, dict) and response.get("error"):
|
|
380
|
+
raise GuardrailsClientError(f"API Error: {str(response)}")
|
|
381
381
|
return GuardrailsListPoliciesResponse.from_dict(response)
|
|
382
382
|
except Exception as e:
|
|
383
383
|
raise GuardrailsClientError(str(e))
|
enkryptai_sdk/models.py
CHANGED
|
@@ -15,18 +15,20 @@ class ModelClient(BaseClient):
|
|
|
15
15
|
def __init__(self, api_key: str, base_url: str = "https://api.enkryptai.com:443"):
|
|
16
16
|
super().__init__(api_key, base_url)
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
@staticmethod
|
|
19
|
+
def prepare_model_payload(config: ModelConfig | dict, is_custom: bool = False) -> dict:
|
|
19
20
|
"""
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
Prepare the payload for model operations from a config object.
|
|
22
|
+
|
|
22
23
|
Args:
|
|
23
|
-
config (ModelConfig): Configuration object containing model details
|
|
24
|
-
|
|
24
|
+
config (Union[ModelConfig, dict]): Configuration object or dictionary containing model details
|
|
25
|
+
|
|
25
26
|
Returns:
|
|
26
|
-
dict:
|
|
27
|
+
dict: Processed payload ready for API submission
|
|
27
28
|
"""
|
|
28
|
-
|
|
29
|
-
|
|
29
|
+
if isinstance(config, dict):
|
|
30
|
+
config = ModelConfig.from_dict(config)
|
|
31
|
+
|
|
30
32
|
# Parse endpoint_url into components
|
|
31
33
|
parsed_url = urlparse(config.model_config.endpoint_url)
|
|
32
34
|
path_parts = parsed_url.path.strip("/").split("/")
|
|
@@ -43,15 +45,11 @@ class ModelClient(BaseClient):
|
|
|
43
45
|
paths = config.model_config.paths.to_dict()
|
|
44
46
|
else:
|
|
45
47
|
paths = {
|
|
46
|
-
"completions": (
|
|
47
|
-
f"/{remaining_path.split('/')[-1]}" if remaining_path else ""
|
|
48
|
-
),
|
|
48
|
+
"completions": f"/{remaining_path.split('/')[-1]}" if remaining_path else "",
|
|
49
49
|
"chat": f"/{remaining_path}" if remaining_path else "",
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
payload = {
|
|
53
|
-
"model_saved_name": config.model_saved_name,
|
|
54
|
-
"model_version": config.model_version,
|
|
55
53
|
"testing_for": config.testing_for,
|
|
56
54
|
"model_name": config.model_name,
|
|
57
55
|
"certifications": config.certifications,
|
|
@@ -63,9 +61,8 @@ class ModelClient(BaseClient):
|
|
|
63
61
|
"endpoint": {
|
|
64
62
|
"scheme": parsed_url.scheme,
|
|
65
63
|
"host": parsed_url.hostname,
|
|
66
|
-
"port": parsed_url.port
|
|
67
|
-
|
|
68
|
-
"base_path": f"/{base_path}", # Just v1
|
|
64
|
+
"port": parsed_url.port or (443 if parsed_url.scheme == "https" else 80),
|
|
65
|
+
"base_path": f"/{base_path}",
|
|
69
66
|
},
|
|
70
67
|
"paths": paths,
|
|
71
68
|
"auth_data": {
|
|
@@ -73,9 +70,7 @@ class ModelClient(BaseClient):
|
|
|
73
70
|
"header_prefix": config.model_config.auth_data.header_prefix,
|
|
74
71
|
"space_after_prefix": config.model_config.auth_data.space_after_prefix,
|
|
75
72
|
},
|
|
76
|
-
"apikeys":
|
|
77
|
-
[config.model_config.apikey] if config.model_config.apikey else []
|
|
78
|
-
),
|
|
73
|
+
"apikeys": [config.model_config.apikey] if config.model_config.apikey else [],
|
|
79
74
|
"tools": config.model_config.tools,
|
|
80
75
|
"input_modalities": config.model_config.input_modalities,
|
|
81
76
|
"output_modalities": config.model_config.output_modalities,
|
|
@@ -87,12 +82,32 @@ class ModelClient(BaseClient):
|
|
|
87
82
|
"default_request_options": config.model_config.default_request_options,
|
|
88
83
|
},
|
|
89
84
|
}
|
|
85
|
+
|
|
86
|
+
if not is_custom:
|
|
87
|
+
payload["model_saved_name"] = config.model_saved_name
|
|
88
|
+
payload["model_version"] = config.model_version
|
|
89
|
+
|
|
90
|
+
return payload
|
|
91
|
+
|
|
92
|
+
def add_model(self, config: ModelConfig) -> ModelResponse:
|
|
93
|
+
"""
|
|
94
|
+
Add a new model configuration to the system.
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
config (ModelConfig): Configuration object containing model details
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
dict: Response from the API containing the added model details
|
|
101
|
+
"""
|
|
102
|
+
headers = {"Content-Type": "application/json"}
|
|
103
|
+
payload = self.prepare_model_payload(config)
|
|
104
|
+
|
|
90
105
|
try:
|
|
91
106
|
response = self._request(
|
|
92
107
|
"POST", "/models/add-model", headers=headers, json=payload
|
|
93
108
|
)
|
|
94
109
|
if response.get("error"):
|
|
95
|
-
raise ModelClientError(response
|
|
110
|
+
raise ModelClientError(f"API Error: {str(response)}")
|
|
96
111
|
return ModelResponse.from_dict(response)
|
|
97
112
|
except Exception as e:
|
|
98
113
|
raise ModelClientError(str(e))
|
|
@@ -112,7 +127,7 @@ class ModelClient(BaseClient):
|
|
|
112
127
|
response = self._request("GET", "/models/get-model", headers=headers)
|
|
113
128
|
# print(response)
|
|
114
129
|
if response.get("error"):
|
|
115
|
-
raise ModelClientError(response
|
|
130
|
+
raise ModelClientError(f"API Error: {str(response)}")
|
|
116
131
|
return ModelConfig.from_dict(response)
|
|
117
132
|
|
|
118
133
|
def get_model_list(self):
|
|
@@ -124,8 +139,8 @@ class ModelClient(BaseClient):
|
|
|
124
139
|
"""
|
|
125
140
|
try:
|
|
126
141
|
response = self._request("GET", "/models/list-models")
|
|
127
|
-
if response.get("error"):
|
|
128
|
-
raise ModelClientError(response
|
|
142
|
+
if isinstance(response, dict) and response.get("error"):
|
|
143
|
+
raise ModelClientError(f"API Error: {str(response)}")
|
|
129
144
|
return ModelCollection.from_dict(response)
|
|
130
145
|
except Exception as e:
|
|
131
146
|
return {"error": str(e)}
|
|
@@ -217,7 +232,7 @@ class ModelClient(BaseClient):
|
|
|
217
232
|
"PATCH", "/models/modify-model", headers=headers, json=payload
|
|
218
233
|
)
|
|
219
234
|
if response.get("error"):
|
|
220
|
-
raise ModelClientError(response
|
|
235
|
+
raise ModelClientError(f"API Error: {str(response)}")
|
|
221
236
|
return ModelResponse.from_dict(response)
|
|
222
237
|
except Exception as e:
|
|
223
238
|
raise ModelClientError(str(e))
|
|
@@ -238,7 +253,7 @@ class ModelClient(BaseClient):
|
|
|
238
253
|
try:
|
|
239
254
|
response = self._request("DELETE", "/models/delete-model", headers=headers)
|
|
240
255
|
if response.get("error"):
|
|
241
|
-
raise ModelClientError(response
|
|
256
|
+
raise ModelClientError(f"API Error: {str(response)}")
|
|
242
257
|
return ModelResponse.from_dict(response)
|
|
243
258
|
except Exception as e:
|
|
244
259
|
raise ModelClientError(str(e))
|
enkryptai_sdk/red_team.py
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import urllib3
|
|
2
2
|
from .base import BaseClient
|
|
3
|
+
from .models import ModelClient
|
|
4
|
+
from .datasets import DatasetClient
|
|
3
5
|
from .dto import (
|
|
4
6
|
RedteamHealthResponse,
|
|
5
7
|
RedTeamModelHealthConfig,
|
|
6
8
|
RedteamModelHealthResponse,
|
|
7
9
|
RedTeamConfig,
|
|
8
10
|
RedTeamConfigWithSavedModel,
|
|
11
|
+
RedTeamCustomConfig,
|
|
12
|
+
RedTeamCustomConfigWithSavedModel,
|
|
9
13
|
RedTeamResponse,
|
|
10
14
|
RedTeamResultSummary,
|
|
11
15
|
RedTeamResultDetails,
|
|
@@ -47,7 +51,7 @@ class RedTeamClient(BaseClient):
|
|
|
47
51
|
try:
|
|
48
52
|
response = self._request("GET", "/redteam/health")
|
|
49
53
|
if response.get("error"):
|
|
50
|
-
raise RedTeamClientError(response
|
|
54
|
+
raise RedTeamClientError(f"API Error: {str(response)}")
|
|
51
55
|
return RedteamHealthResponse.from_dict(response)
|
|
52
56
|
except Exception as e:
|
|
53
57
|
raise RedTeamClientError(str(e))
|
|
@@ -61,7 +65,7 @@ class RedTeamClient(BaseClient):
|
|
|
61
65
|
response = self._request("POST", "/redteam/model-health", json=config.to_dict())
|
|
62
66
|
# if response.get("error"):
|
|
63
67
|
if response.get("error") not in [None, ""]:
|
|
64
|
-
raise RedTeamClientError(response
|
|
68
|
+
raise RedTeamClientError(f"API Error: {str(response)}")
|
|
65
69
|
return RedteamModelHealthResponse.from_dict(response)
|
|
66
70
|
except Exception as e:
|
|
67
71
|
raise RedTeamClientError(str(e))
|
|
@@ -78,7 +82,7 @@ class RedTeamClient(BaseClient):
|
|
|
78
82
|
response = self._request("POST", "/redteam/model/model-health", headers=headers)
|
|
79
83
|
# if response.get("error"):
|
|
80
84
|
if response.get("error") not in [None, ""]:
|
|
81
|
-
raise RedTeamClientError(response
|
|
85
|
+
raise RedTeamClientError(f"API Error: {str(response)}")
|
|
82
86
|
return RedteamModelHealthResponse.from_dict(response)
|
|
83
87
|
except Exception as e:
|
|
84
88
|
raise RedTeamClientError(str(e))
|
|
@@ -115,7 +119,7 @@ class RedTeamClient(BaseClient):
|
|
|
115
119
|
json=payload,
|
|
116
120
|
)
|
|
117
121
|
if response.get("error"):
|
|
118
|
-
raise RedTeamClientError(response
|
|
122
|
+
raise RedTeamClientError(f"API Error: {str(response)}")
|
|
119
123
|
return RedTeamResponse.from_dict(response)
|
|
120
124
|
else:
|
|
121
125
|
raise RedTeamClientError(
|
|
@@ -163,7 +167,118 @@ class RedTeamClient(BaseClient):
|
|
|
163
167
|
json=payload,
|
|
164
168
|
)
|
|
165
169
|
if response.get("error"):
|
|
166
|
-
raise RedTeamClientError(response
|
|
170
|
+
raise RedTeamClientError(f"API Error: {str(response)}")
|
|
171
|
+
return RedTeamResponse.from_dict(response)
|
|
172
|
+
|
|
173
|
+
def add_custom_task(
|
|
174
|
+
self,
|
|
175
|
+
config: RedTeamCustomConfig,
|
|
176
|
+
policy_name: str = None,
|
|
177
|
+
):
|
|
178
|
+
"""
|
|
179
|
+
Add a new custom red teaming task.
|
|
180
|
+
"""
|
|
181
|
+
headers = {
|
|
182
|
+
"Content-Type": "application/json",
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if policy_name is not None:
|
|
186
|
+
headers["X-Enkrypt-Policy"] = policy_name
|
|
187
|
+
|
|
188
|
+
config = RedTeamCustomConfig.from_dict(config)
|
|
189
|
+
test_configs = config.redteam_test_configurations.to_dict()
|
|
190
|
+
# Remove None or empty test configurations
|
|
191
|
+
test_configs = {k: v for k, v in test_configs.items() if v is not None}
|
|
192
|
+
|
|
193
|
+
payload = {
|
|
194
|
+
# "async": config.async_enabled,
|
|
195
|
+
"test_name": config.test_name,
|
|
196
|
+
"redteam_test_configurations": {
|
|
197
|
+
k: v.to_dict() for k, v in test_configs.items()
|
|
198
|
+
},
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
if config.dataset_configuration:
|
|
202
|
+
payload["dataset_configuration"] = DatasetClient.prepare_dataset_payload(
|
|
203
|
+
config.dataset_configuration, True)
|
|
204
|
+
else:
|
|
205
|
+
raise RedTeamClientError(
|
|
206
|
+
"Please provide a dataset configuration"
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
if config.endpoint_configuration:
|
|
210
|
+
payload["endpoint_configuration"] = ModelClient.prepare_model_payload(
|
|
211
|
+
config.endpoint_configuration, True)
|
|
212
|
+
# print(payload)
|
|
213
|
+
|
|
214
|
+
response = self._request(
|
|
215
|
+
"POST",
|
|
216
|
+
"/redteam/v2/add-custom-task",
|
|
217
|
+
headers=headers,
|
|
218
|
+
json=payload,
|
|
219
|
+
)
|
|
220
|
+
if response.get("error"):
|
|
221
|
+
raise RedTeamClientError(f"API Error: {str(response)}")
|
|
222
|
+
return RedTeamResponse.from_dict(response)
|
|
223
|
+
else:
|
|
224
|
+
raise RedTeamClientError(
|
|
225
|
+
"Please provide a endpoint configuration"
|
|
226
|
+
)
|
|
227
|
+
|
|
228
|
+
def add_custom_task_with_saved_model(
|
|
229
|
+
self,
|
|
230
|
+
config: RedTeamCustomConfigWithSavedModel,
|
|
231
|
+
model_saved_name: str,
|
|
232
|
+
model_version: str,
|
|
233
|
+
policy_name: str = None,
|
|
234
|
+
):
|
|
235
|
+
"""
|
|
236
|
+
Add a new red teaming custom task using a saved model.
|
|
237
|
+
"""
|
|
238
|
+
if not model_saved_name:
|
|
239
|
+
raise RedTeamClientError("Please provide a model_saved_name")
|
|
240
|
+
|
|
241
|
+
if not model_version:
|
|
242
|
+
raise RedTeamClientError("Please provide a model_version. Default is 'v1'")
|
|
243
|
+
|
|
244
|
+
config = RedTeamCustomConfigWithSavedModel.from_dict(config)
|
|
245
|
+
test_configs = config.redteam_test_configurations.to_dict()
|
|
246
|
+
# Remove None or empty test configurations
|
|
247
|
+
test_configs = {k: v for k, v in test_configs.items() if v is not None}
|
|
248
|
+
|
|
249
|
+
payload = {
|
|
250
|
+
# "async": config.async_enabled,
|
|
251
|
+
"test_name": config.test_name,
|
|
252
|
+
"redteam_test_configurations": {
|
|
253
|
+
k: v.to_dict() for k, v in test_configs.items()
|
|
254
|
+
},
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
if config.dataset_configuration:
|
|
258
|
+
payload["dataset_configuration"] = DatasetClient.prepare_dataset_payload(
|
|
259
|
+
config.dataset_configuration, True)
|
|
260
|
+
else:
|
|
261
|
+
raise RedTeamClientError(
|
|
262
|
+
"Please provide a dataset configuration"
|
|
263
|
+
)
|
|
264
|
+
|
|
265
|
+
headers = {
|
|
266
|
+
"X-Enkrypt-Model": model_saved_name,
|
|
267
|
+
"X-Enkrypt-Model-Version": model_version,
|
|
268
|
+
"Content-Type": "application/json",
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
if policy_name is not None:
|
|
272
|
+
headers["X-Enkrypt-Policy"] = policy_name
|
|
273
|
+
|
|
274
|
+
response = self._request(
|
|
275
|
+
"POST",
|
|
276
|
+
"/redteam/v2/model/add-custom-task",
|
|
277
|
+
headers=headers,
|
|
278
|
+
json=payload,
|
|
279
|
+
)
|
|
280
|
+
if response.get("error"):
|
|
281
|
+
raise RedTeamClientError(f"API Error: {str(response)}")
|
|
167
282
|
return RedTeamResponse.from_dict(response)
|
|
168
283
|
|
|
169
284
|
def status(self, task_id: str = None, test_name: str = None):
|
|
@@ -191,7 +306,7 @@ class RedTeamClient(BaseClient):
|
|
|
191
306
|
|
|
192
307
|
response = self._request("GET", "/redteam/task-status", headers=headers)
|
|
193
308
|
if response.get("error"):
|
|
194
|
-
raise RedTeamClientError(response
|
|
309
|
+
raise RedTeamClientError(f"API Error: {str(response)}")
|
|
195
310
|
return RedTeamTaskStatus.from_dict(response)
|
|
196
311
|
|
|
197
312
|
def cancel_task(self, task_id: str = None, test_name: str = None):
|
|
@@ -224,7 +339,7 @@ class RedTeamClient(BaseClient):
|
|
|
224
339
|
|
|
225
340
|
response = self._request("POST", "/redteam/cancel-task", headers=headers)
|
|
226
341
|
if response.get("error"):
|
|
227
|
-
raise RedTeamClientError(response
|
|
342
|
+
raise RedTeamClientError(f"API Error: {str(response)}")
|
|
228
343
|
return response
|
|
229
344
|
|
|
230
345
|
def get_task(self, task_id: str = None, test_name: str = None):
|
|
@@ -252,7 +367,7 @@ class RedTeamClient(BaseClient):
|
|
|
252
367
|
|
|
253
368
|
response = self._request("GET", "/redteam/get-task", headers=headers)
|
|
254
369
|
if response.get("error"):
|
|
255
|
-
raise RedTeamClientError(response
|
|
370
|
+
raise RedTeamClientError(f"API Error: {str(response)}")
|
|
256
371
|
return RedTeamTaskDetails.from_dict(response["data"])
|
|
257
372
|
|
|
258
373
|
def get_result_summary(self, task_id: str = None, test_name: str = None):
|
|
@@ -280,7 +395,7 @@ class RedTeamClient(BaseClient):
|
|
|
280
395
|
|
|
281
396
|
response = self._request("GET", "/redteam/results/summary", headers=headers)
|
|
282
397
|
if response.get("error"):
|
|
283
|
-
raise RedTeamClientError(response
|
|
398
|
+
raise RedTeamClientError(f"API Error: {str(response)}")
|
|
284
399
|
# print(f"Response: {response}")
|
|
285
400
|
return RedTeamResultSummary.from_dict(response)
|
|
286
401
|
|
|
@@ -314,7 +429,7 @@ class RedTeamClient(BaseClient):
|
|
|
314
429
|
url = f"/redteam/v2/results/summary/{test_type}"
|
|
315
430
|
response = self._request("GET", url, headers=headers)
|
|
316
431
|
if response.get("error"):
|
|
317
|
-
raise RedTeamClientError(response
|
|
432
|
+
raise RedTeamClientError(f"API Error: {str(response)}")
|
|
318
433
|
# print(f"Response: {response}")
|
|
319
434
|
return RedTeamResultSummary.from_dict(response)
|
|
320
435
|
|
|
@@ -343,7 +458,7 @@ class RedTeamClient(BaseClient):
|
|
|
343
458
|
|
|
344
459
|
response = self._request("GET", "/redteam/v2/results/details", headers=headers)
|
|
345
460
|
if response.get("error"):
|
|
346
|
-
raise RedTeamClientError(response
|
|
461
|
+
raise RedTeamClientError(f"API Error: {str(response)}")
|
|
347
462
|
return RedTeamResultDetails.from_dict(response)
|
|
348
463
|
|
|
349
464
|
def get_result_details_test_type(self, task_id: str = None, test_name: str = None, test_type: str = None):
|
|
@@ -377,7 +492,7 @@ class RedTeamClient(BaseClient):
|
|
|
377
492
|
url = f"/redteam/v2/results/details/{test_type}"
|
|
378
493
|
response = self._request("GET", url, headers=headers)
|
|
379
494
|
if response.get("error"):
|
|
380
|
-
raise RedTeamClientError(response
|
|
495
|
+
raise RedTeamClientError(f"API Error: {str(response)}")
|
|
381
496
|
return RedTeamResultDetails.from_dict(response)
|
|
382
497
|
|
|
383
498
|
def get_task_list(self, status: str = None):
|
|
@@ -395,6 +510,6 @@ class RedTeamClient(BaseClient):
|
|
|
395
510
|
url += f"?status={status}"
|
|
396
511
|
|
|
397
512
|
response = self._request("GET", url)
|
|
398
|
-
if response.get("error"):
|
|
399
|
-
raise RedTeamClientError(response
|
|
513
|
+
if isinstance(response, dict) and response.get("error"):
|
|
514
|
+
raise RedTeamClientError(f"API Error: {str(response)}")
|
|
400
515
|
return RedTeamTaskList.from_dict(response)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: enkryptai-sdk
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.8
|
|
4
4
|
Summary: A Python SDK with guardrails and red teaming functionality for API interactions
|
|
5
5
|
Home-page: https://github.com/enkryptai/enkryptai-sdk
|
|
6
6
|
Author: Enkrypt AI Team
|
|
@@ -47,6 +47,8 @@ Also see the API documentation at [https://docs.enkryptai.com](https://docs.enkr
|
|
|
47
47
|
- [Sample Redteam Model Health Config](#sample-redteam-model-health-config)
|
|
48
48
|
- [Sample Redteam Target Config](#sample-redteam-target-config)
|
|
49
49
|
- [Sample Redteam Model Config](#sample-redteam-model-config)
|
|
50
|
+
- [Sample Custom Redteam Target Config](#sample-custom-redteam-target-config)
|
|
51
|
+
- [Sample Custom Redteam Model Config](#sample-custom-redteam-model-config)
|
|
50
52
|
- [Health Checks](#health-checks)
|
|
51
53
|
- [Guardrails Health](#guardrails-health)
|
|
52
54
|
- [Guardrails Status](#guardrails-status)
|
|
@@ -106,6 +108,8 @@ Also see the API documentation at [https://docs.enkryptai.com](https://docs.enkr
|
|
|
106
108
|
- [Redteam](#redteam)
|
|
107
109
|
- [Add a Redteam Task with Target Model Config](#add-a-redteam-task-with-target-model-config)
|
|
108
110
|
- [Add a Redteam Task with a saved model](#add-a-redteam-task-with-a-saved-model)
|
|
111
|
+
- [Add a Redteam Custom Task with Endpoint Config](#add-a-redteam-custom-task-with-endpoint-config)
|
|
112
|
+
- [Add a Redteam Custom Task with a saved model](#add-a-redteam-custom-task-with-a-saved-model)
|
|
109
113
|
- [Get Redteam Task Status](#get-redteam-task-status)
|
|
110
114
|
- [Get Redteam Task](#get-redteam-task)
|
|
111
115
|
- [List Redteam Tasks](#list-redteam-tasks)
|
|
@@ -193,6 +197,7 @@ pii_anonymized_text = None
|
|
|
193
197
|
dataset_name = f"TestElectionDataset-{str(uuid.uuid4())[:8]}"
|
|
194
198
|
|
|
195
199
|
redteam_test_name = f"Redteam Test {str(uuid.uuid4())[:6]}"
|
|
200
|
+
custom_redteam_test_name = f"Custom Redteam Test {str(uuid.uuid4())[:6]}"
|
|
196
201
|
|
|
197
202
|
model_name = "gpt-4o-mini"
|
|
198
203
|
model_provider = "openai"
|
|
@@ -422,6 +427,82 @@ sample_redteam_model_config = {
|
|
|
422
427
|
}
|
|
423
428
|
```
|
|
424
429
|
|
|
430
|
+
### [Sample Custom Redteam Target Config](https://docs.enkryptai.com/redteam-api-reference/endpoint/add-custom-task)
|
|
431
|
+
|
|
432
|
+
```python Python
|
|
433
|
+
sample_custom_redteam_target_config = {
|
|
434
|
+
"test_name": custom_redteam_test_name,
|
|
435
|
+
"dataset_configuration": {
|
|
436
|
+
"system_description": "- **Voter Eligibility**: To vote in U.S. elections, individuals must be U.S. citizens, at least 18 years old by election day, and meet their state's residency requirements. - **Voter Registration**: Most states require voters to register ahead of time, with deadlines varying widely. North Dakota is an exception, as it does not require voter registration. - **Identification Requirements**: Thirty-six states enforce voter ID laws, requiring individuals to present identification at polling places. These laws aim to prevent voter fraud but can also lead to disenfranchisement. - **Voting Methods**: Voters can typically choose between in-person voting on election day, early voting, and absentee or mail-in ballots, depending on state regulations. - **Polling Hours**: Polling hours vary by state, with some states allowing extended hours for voters. Its essential for voters to check local polling times to ensure they can cast their ballots. - **Provisional Ballots**: If there are questions about a voter's eligibility, they may be allowed to cast a provisional ballot. This ballot is counted once eligibility is confirmed. - **Election Day Laws**: Many states have laws that protect the rights of voters on election day, including prohibiting intimidation and ensuring access to polling places. - **Campaign Finance Regulations**: Federal and state laws regulate contributions to candidates and political parties to ensure transparency and limit the influence of money in politics. - **Political Advertising**: Campaigns must adhere to rules regarding political advertising, including disclosure requirements about funding sources and content accuracy. - **Voter Intimidation Prohibitions**: Federal laws prohibit any form of voter intimidation or coercion at polling places, ensuring a safe environment for all voters. - **Accessibility Requirements**: The Americans with Disabilities Act mandates that polling places be accessible to individuals with disabilities, ensuring equal access to the electoral process. - **Election Monitoring**: Various organizations are allowed to monitor elections to ensure compliance with laws and regulations. They help maintain transparency and accountability in the electoral process. - **Vote Counting Procedures**: States have specific procedures for counting votes, including the use of electronic voting machines and manual audits to verify results. - **Ballot Design Standards**: States must adhere to certain design standards for ballots to ensure clarity and prevent confusion among voters when casting their votes. - **Post-Election Audits**: Some states conduct post-election audits as a measure of accuracy. These audits help verify that the vote count reflects the actual ballots cast.",
|
|
437
|
+
"policy_description": "Do not generate any content that is illegal, harmful, or violates the rights of others.",
|
|
438
|
+
# "risk_categories": "",
|
|
439
|
+
"tools": [
|
|
440
|
+
{
|
|
441
|
+
"name": "web_search",
|
|
442
|
+
"description": "The tool web search is used to search the web for information related to finance."
|
|
443
|
+
}
|
|
444
|
+
],
|
|
445
|
+
"max_prompts": 100,
|
|
446
|
+
"scenarios": 2,
|
|
447
|
+
"categories": 2,
|
|
448
|
+
"depth": 2,
|
|
449
|
+
},
|
|
450
|
+
"redteam_test_configurations": {
|
|
451
|
+
"harmful_test": {
|
|
452
|
+
"sample_percentage": 2,
|
|
453
|
+
"attack_methods": {"basic": ["basic"]},
|
|
454
|
+
},
|
|
455
|
+
"custom_test": {
|
|
456
|
+
"sample_percentage": 2,
|
|
457
|
+
"attack_methods": {"basic": ["basic"]},
|
|
458
|
+
},
|
|
459
|
+
},
|
|
460
|
+
"endpoint_configuration": {
|
|
461
|
+
"testing_for": "foundationModels",
|
|
462
|
+
"model_name": model_name,
|
|
463
|
+
"model_config": {
|
|
464
|
+
"model_provider": model_provider,
|
|
465
|
+
"endpoint_url": model_endpoint_url,
|
|
466
|
+
"apikey": OPENAI_API_KEY,
|
|
467
|
+
"input_modalities": ["text"],
|
|
468
|
+
"output_modalities": ["text"],
|
|
469
|
+
},
|
|
470
|
+
},
|
|
471
|
+
}
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
### [Sample Custom Redteam Model Config](https://docs.enkryptai.com/redteam-api-reference/endpoint/model-add-custom-task)
|
|
475
|
+
|
|
476
|
+
```python Python
|
|
477
|
+
sample_custom_redteam_model_config = {
|
|
478
|
+
"test_name": custom_redteam_test_name,
|
|
479
|
+
"dataset_configuration": {
|
|
480
|
+
"system_description": "- **Voter Eligibility**: To vote in U.S. elections, individuals must be U.S. citizens, at least 18 years old by election day, and meet their state's residency requirements. - **Voter Registration**: Most states require voters to register ahead of time, with deadlines varying widely. North Dakota is an exception, as it does not require voter registration. - **Identification Requirements**: Thirty-six states enforce voter ID laws, requiring individuals to present identification at polling places. These laws aim to prevent voter fraud but can also lead to disenfranchisement. - **Voting Methods**: Voters can typically choose between in-person voting on election day, early voting, and absentee or mail-in ballots, depending on state regulations. - **Polling Hours**: Polling hours vary by state, with some states allowing extended hours for voters. Its essential for voters to check local polling times to ensure they can cast their ballots. - **Provisional Ballots**: If there are questions about a voter's eligibility, they may be allowed to cast a provisional ballot. This ballot is counted once eligibility is confirmed. - **Election Day Laws**: Many states have laws that protect the rights of voters on election day, including prohibiting intimidation and ensuring access to polling places. - **Campaign Finance Regulations**: Federal and state laws regulate contributions to candidates and political parties to ensure transparency and limit the influence of money in politics. - **Political Advertising**: Campaigns must adhere to rules regarding political advertising, including disclosure requirements about funding sources and content accuracy. - **Voter Intimidation Prohibitions**: Federal laws prohibit any form of voter intimidation or coercion at polling places, ensuring a safe environment for all voters. - **Accessibility Requirements**: The Americans with Disabilities Act mandates that polling places be accessible to individuals with disabilities, ensuring equal access to the electoral process. - **Election Monitoring**: Various organizations are allowed to monitor elections to ensure compliance with laws and regulations. They help maintain transparency and accountability in the electoral process. - **Vote Counting Procedures**: States have specific procedures for counting votes, including the use of electronic voting machines and manual audits to verify results. - **Ballot Design Standards**: States must adhere to certain design standards for ballots to ensure clarity and prevent confusion among voters when casting their votes. - **Post-Election Audits**: Some states conduct post-election audits as a measure of accuracy. These audits help verify that the vote count reflects the actual ballots cast.",
|
|
481
|
+
"policy_description": "Do not generate any content that is illegal, harmful, or violates the rights of others.",
|
|
482
|
+
"tools": [
|
|
483
|
+
{
|
|
484
|
+
"name": "web_search",
|
|
485
|
+
"description": "The tool web search is used to search the web for information related to finance."
|
|
486
|
+
}
|
|
487
|
+
],
|
|
488
|
+
"max_prompts": 100,
|
|
489
|
+
"scenarios": 2,
|
|
490
|
+
"categories": 2,
|
|
491
|
+
"depth": 2,
|
|
492
|
+
},
|
|
493
|
+
"redteam_test_configurations": {
|
|
494
|
+
"harmful_test": {
|
|
495
|
+
"sample_percentage": 2,
|
|
496
|
+
"attack_methods": {"basic": ["basic"]},
|
|
497
|
+
},
|
|
498
|
+
"custom_test": {
|
|
499
|
+
"sample_percentage": 2,
|
|
500
|
+
"attack_methods": {"basic": ["basic"]},
|
|
501
|
+
},
|
|
502
|
+
},
|
|
503
|
+
}
|
|
504
|
+
```
|
|
505
|
+
|
|
425
506
|
## Health Checks
|
|
426
507
|
|
|
427
508
|
### [Guardrails Health](https://docs.enkryptai.com/guardrails-api-reference/endpoint/health-check)
|
|
@@ -1292,6 +1373,40 @@ assert add_redteam_model_response.message == "Redteam task has been added succes
|
|
|
1292
1373
|
print(add_redteam_model_response.to_dict())
|
|
1293
1374
|
```
|
|
1294
1375
|
|
|
1376
|
+
### [Add a Redteam Custom Task with Endpoint Config](https://docs.enkryptai.com/redteam-api-reference/endpoint/add-custom-task)
|
|
1377
|
+
|
|
1378
|
+
```python Python
|
|
1379
|
+
# Use a dictionary to configure a redteam task
|
|
1380
|
+
add_custom_redteam_target_response = redteam_client.add_custom_task(config=copy.deepcopy(sample_custom_redteam_target_config))
|
|
1381
|
+
|
|
1382
|
+
# If you already saved a Code of Conduct Policy and want to use it, then instead of passing `dataset_configuration.policy_description` in the body, you can use the SDK like this:
|
|
1383
|
+
add_custom_redteam_target_response = redteam_client.add_custom_task(config=copy.deepcopy(sample_custom_redteam_target_config), policy_name="Code of Conduct Policy")
|
|
1384
|
+
|
|
1385
|
+
print(add_custom_redteam_target_response)
|
|
1386
|
+
|
|
1387
|
+
assert add_custom_redteam_target_response.message == "Task submitted successfully"
|
|
1388
|
+
|
|
1389
|
+
# Print as a dictionary
|
|
1390
|
+
print(add_custom_redteam_target_response.to_dict())
|
|
1391
|
+
```
|
|
1392
|
+
|
|
1393
|
+
### [Add a Redteam Custom Task with a saved model](https://docs.enkryptai.com/redteam-api-reference/endpoint/model-add-custom-task)
|
|
1394
|
+
|
|
1395
|
+
```python Python
|
|
1396
|
+
# Use a dictionary to configure a redteam task
|
|
1397
|
+
add_custom_redteam_target_response = redteam_client.add_custom_task_with_saved_model(config=copy.deepcopy(sample_custom_redteam_model_config),model_saved_name=test_model_saved_name,model_version="v1")
|
|
1398
|
+
|
|
1399
|
+
# If you already saved a Code of Conduct Policy and want to use it, then instead of passing `dataset_configuration.policy_description` in the body, you can use the SDK like this:
|
|
1400
|
+
add_custom_redteam_target_response = redteam_client.add_custom_task_with_saved_model(config=copy.deepcopy(sample_custom_redteam_model_config),model_saved_name=test_model_saved_name,model_version="v1",policy_name="Code of Conduct Policy")
|
|
1401
|
+
|
|
1402
|
+
print(add_custom_redteam_target_response)
|
|
1403
|
+
|
|
1404
|
+
assert add_custom_redteam_target_response.message == "Task submitted successfully"
|
|
1405
|
+
|
|
1406
|
+
# Print as a dictionary
|
|
1407
|
+
print(add_custom_redteam_target_response.to_dict())
|
|
1408
|
+
```
|
|
1409
|
+
|
|
1295
1410
|
### [Get Redteam Task Status](https://docs.enkryptai.com/redteam-api-reference/endpoint/get-task-status)
|
|
1296
1411
|
|
|
1297
1412
|
```python Python
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
enkryptai_sdk/__init__.py,sha256=rP6PtntJogJauj1lKWK8DkiBr3uYjireIUamr6aflu0,763
|
|
2
|
+
enkryptai_sdk/ai_proxy.py,sha256=ot1lqKk2LjcvlpnFm2kSA51vFThfquVlx86BhSbAzBo,3823
|
|
3
|
+
enkryptai_sdk/base.py,sha256=MlEDcEIjXo35kat9XkGUu7VB2fIvJk38C94wAeO9bEw,1304
|
|
4
|
+
enkryptai_sdk/config.py,sha256=IpB8_aO4zXdvv061v24oh83oyJ5Tp1QBQTzeuW4h9QY,8828
|
|
5
|
+
enkryptai_sdk/datasets.py,sha256=RQIR6spI2STXeVolYzBt6gPv6PD5AGh9krs16aKWdWA,6067
|
|
6
|
+
enkryptai_sdk/deployments.py,sha256=A7XZ2JwrMod9V4_aV8bFY_Soh9E3jHdwaTuJ9BwXuyk,4215
|
|
7
|
+
enkryptai_sdk/evals.py,sha256=BywyEgIT7xdJ58svO_sDNOMVowdB0RTGoAZPEbCnDVo,2595
|
|
8
|
+
enkryptai_sdk/guardrails.py,sha256=I5D8OxvJzz7t2jXNqNUj0_1Kl5K0b8zyPsXWAwiZu2o,13853
|
|
9
|
+
enkryptai_sdk/guardrails_old.py,sha256=SgzPZkTzbAPD9XfmYNG6M1-TrzbhDHpAkI3FjnVWS_s,6434
|
|
10
|
+
enkryptai_sdk/models.py,sha256=2H316e28Ssi_MHck0pAoydThRYSdAeSOlwwAoU7q86Q,10941
|
|
11
|
+
enkryptai_sdk/red_team.py,sha256=sJbhCuPfI9aowGvV71hRZslBp1HQa7bklbb89HU5tk8,18574
|
|
12
|
+
enkryptai_sdk/response.py,sha256=43JRubzgGCpoVxYNzBZY0AlUgLbfcXD_AwD7wU3qY9o,4086
|
|
13
|
+
enkryptai_sdk/dto/__init__.py,sha256=RMhr9QKMFuJVXQt3yN7uFwcFpX4PkRvqxjg3ZySUnjg,2505
|
|
14
|
+
enkryptai_sdk/dto/ai_proxy.py,sha256=clwMN4xdH8Zr55dnhilHbs-qaHRlCOrLPrij0Zd1Av0,11283
|
|
15
|
+
enkryptai_sdk/dto/base.py,sha256=6VWTkoNZ7uILqn_iYsPS21cVa2xLYpw5bjDIsRCS5tk,2389
|
|
16
|
+
enkryptai_sdk/dto/datasets.py,sha256=RFA9CmbhD-QDDyweBq_k9iBd00b6I6SWmdP9DPNd9fc,5002
|
|
17
|
+
enkryptai_sdk/dto/deployments.py,sha256=Aw4b8tDA3FYIomqDvCjblCXTagL4bT8Fx91X0SFXs40,11216
|
|
18
|
+
enkryptai_sdk/dto/guardrails.py,sha256=uolGPPF4v0l76MI5G0ofTtc9-r1l0_sqQqQkLEhAsf0,46305
|
|
19
|
+
enkryptai_sdk/dto/models.py,sha256=lNakMstGozgN_htY2_OItkjQnMQpw5tO9lCZVlywMIg,13442
|
|
20
|
+
enkryptai_sdk/dto/red_team.py,sha256=QtsT4GCnDs24WOF_RMxFtYjvIUULaw5temZ70aduevI,17966
|
|
21
|
+
enkryptai_sdk-1.0.8.dist-info/licenses/LICENSE,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
22
|
+
enkryptai_sdk-1.0.8.dist-info/METADATA,sha256=CXU0oqhE8FABilK7dug8IBcP8OjetArrUXXsFc7fXM8,56401
|
|
23
|
+
enkryptai_sdk-1.0.8.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
|
24
|
+
enkryptai_sdk-1.0.8.dist-info/top_level.txt,sha256=s2X9UJJwvJamNmr6ZXWyyQe60sXtQGWFuaBYfhgHI_4,14
|
|
25
|
+
enkryptai_sdk-1.0.8.dist-info/RECORD,,
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
enkryptai_sdk/__init__.py,sha256=rP6PtntJogJauj1lKWK8DkiBr3uYjireIUamr6aflu0,763
|
|
2
|
-
enkryptai_sdk/ai_proxy.py,sha256=pD6kPmD9H0gttN28cezgV7_IVelLXAHNR5cPeXCM8Ew,3799
|
|
3
|
-
enkryptai_sdk/base.py,sha256=MlEDcEIjXo35kat9XkGUu7VB2fIvJk38C94wAeO9bEw,1304
|
|
4
|
-
enkryptai_sdk/config.py,sha256=IpB8_aO4zXdvv061v24oh83oyJ5Tp1QBQTzeuW4h9QY,8828
|
|
5
|
-
enkryptai_sdk/datasets.py,sha256=2rAU1qeqBZz6rXxG4n9XM_8_ZQYNmcNFW-jgyw7nLPI,5364
|
|
6
|
-
enkryptai_sdk/deployments.py,sha256=qXoUQtLYRSqZsAAqPgxJAad1a3mgMAbPx09NiOyAdsw,4155
|
|
7
|
-
enkryptai_sdk/evals.py,sha256=BywyEgIT7xdJ58svO_sDNOMVowdB0RTGoAZPEbCnDVo,2595
|
|
8
|
-
enkryptai_sdk/guardrails.py,sha256=meR4iZuGV5Js9BRU0edJ82CGOrZMroaTcoaEoUn7k-s,13642
|
|
9
|
-
enkryptai_sdk/guardrails_old.py,sha256=SgzPZkTzbAPD9XfmYNG6M1-TrzbhDHpAkI3FjnVWS_s,6434
|
|
10
|
-
enkryptai_sdk/models.py,sha256=Bj07UAhy2yWAgDxOeInkCTqxDmJK5Ae74v7rNlkA6V4,10361
|
|
11
|
-
enkryptai_sdk/red_team.py,sha256=Puo6BvYDrbERXTuSCFXLtXKhXcFiHuJrcRU5akvXps4,14479
|
|
12
|
-
enkryptai_sdk/response.py,sha256=43JRubzgGCpoVxYNzBZY0AlUgLbfcXD_AwD7wU3qY9o,4086
|
|
13
|
-
enkryptai_sdk/dto/__init__.py,sha256=vG5PmG-L99v89AGiKF1QAF63YILk-e9w0dd665M3U60,2414
|
|
14
|
-
enkryptai_sdk/dto/ai_proxy.py,sha256=clwMN4xdH8Zr55dnhilHbs-qaHRlCOrLPrij0Zd1Av0,11283
|
|
15
|
-
enkryptai_sdk/dto/base.py,sha256=6VWTkoNZ7uILqn_iYsPS21cVa2xLYpw5bjDIsRCS5tk,2389
|
|
16
|
-
enkryptai_sdk/dto/datasets.py,sha256=nI0VjgkViaAi49x01dTDfkzoynx5__zCfJLUsZG8kyw,4846
|
|
17
|
-
enkryptai_sdk/dto/deployments.py,sha256=Aw4b8tDA3FYIomqDvCjblCXTagL4bT8Fx91X0SFXs40,11216
|
|
18
|
-
enkryptai_sdk/dto/guardrails.py,sha256=uolGPPF4v0l76MI5G0ofTtc9-r1l0_sqQqQkLEhAsf0,46305
|
|
19
|
-
enkryptai_sdk/dto/models.py,sha256=6BYF4XwzUwY8O_YgE9S7LPAvsQaRYtUV6ylkTYP7w10,13438
|
|
20
|
-
enkryptai_sdk/dto/red_team.py,sha256=4VGxDGCsZsHi6yJsUZ64IXj6u84xZPcSQuME1PFSnSc,15243
|
|
21
|
-
enkryptai_sdk-1.0.6.dist-info/licenses/LICENSE,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
22
|
-
enkryptai_sdk-1.0.6.dist-info/METADATA,sha256=8htBFgQ36iHitRe08rcvEgB9nnu1pXWBoC3G_i0hdss,45959
|
|
23
|
-
enkryptai_sdk-1.0.6.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
|
|
24
|
-
enkryptai_sdk-1.0.6.dist-info/top_level.txt,sha256=s2X9UJJwvJamNmr6ZXWyyQe60sXtQGWFuaBYfhgHI_4,14
|
|
25
|
-
enkryptai_sdk-1.0.6.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|