enkryptai-sdk 1.0.7__py3-none-any.whl → 1.0.9__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 +3 -0
- enkryptai_sdk/ai_proxy.py +2 -2
- enkryptai_sdk/base.py +52 -3
- enkryptai_sdk/coc.py +203 -0
- enkryptai_sdk/datasets.py +34 -15
- enkryptai_sdk/deployments.py +5 -5
- enkryptai_sdk/dto/__init__.py +12 -1
- enkryptai_sdk/dto/coc.py +159 -0
- enkryptai_sdk/dto/datasets.py +9 -5
- enkryptai_sdk/dto/guardrails.py +109 -4
- enkryptai_sdk/dto/models.py +8 -8
- enkryptai_sdk/dto/red_team.py +84 -1
- enkryptai_sdk/guardrails.py +83 -18
- enkryptai_sdk/models.py +39 -24
- enkryptai_sdk/red_team.py +128 -13
- {enkryptai_sdk-1.0.7.dist-info → enkryptai_sdk-1.0.9.dist-info}/METADATA +266 -14
- enkryptai_sdk-1.0.9.dist-info/RECORD +27 -0
- {enkryptai_sdk-1.0.7.dist-info → enkryptai_sdk-1.0.9.dist-info}/WHEEL +1 -1
- enkryptai_sdk-1.0.7.dist-info/RECORD +0 -25
- {enkryptai_sdk-1.0.7.dist-info → enkryptai_sdk-1.0.9.dist-info}/licenses/LICENSE +0 -0
- {enkryptai_sdk-1.0.7.dist-info → enkryptai_sdk-1.0.9.dist-info}/top_level.txt +0 -0
enkryptai_sdk/__init__.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from .evals import EvalsClient
|
|
2
2
|
from .config import GuardrailsConfig
|
|
3
3
|
from .guardrails import GuardrailsClient, GuardrailsClientError
|
|
4
|
+
from .coc import CoCClient, CoCClientError
|
|
4
5
|
from .models import ModelClient, ModelClientError
|
|
5
6
|
from .red_team import RedTeamClient, RedTeamClientError
|
|
6
7
|
from .datasets import DatasetClient, DatasetClientError
|
|
@@ -11,6 +12,8 @@ __all__ = [
|
|
|
11
12
|
"GuardrailsClient",
|
|
12
13
|
"GuardrailsClientError",
|
|
13
14
|
"GuardrailsConfig",
|
|
15
|
+
"CoCClient",
|
|
16
|
+
"CoCClientError",
|
|
14
17
|
"EvalsClient",
|
|
15
18
|
"ModelClient",
|
|
16
19
|
"RedTeamClient",
|
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/base.py
CHANGED
|
@@ -11,17 +11,65 @@ class BaseClient:
|
|
|
11
11
|
self.http = urllib3.PoolManager()
|
|
12
12
|
self.headers = {"apikey": self.api_key}
|
|
13
13
|
|
|
14
|
-
def _request(self, method, endpoint, payload=None, headers=None, **kwargs):
|
|
14
|
+
# def _request(self, method, endpoint, payload=None, headers=None, **kwargs):
|
|
15
|
+
# url = self.base_url + endpoint
|
|
16
|
+
# request_headers = {
|
|
17
|
+
# "Accept-Encoding": "gzip", # Add required gzip encoding
|
|
18
|
+
# **self.headers,
|
|
19
|
+
# }
|
|
20
|
+
# if headers:
|
|
21
|
+
# request_headers.update(headers)
|
|
22
|
+
|
|
23
|
+
# try:
|
|
24
|
+
# response = self.http.request(method, url, headers=request_headers, **kwargs)
|
|
25
|
+
|
|
26
|
+
# if response.status >= 400:
|
|
27
|
+
# error_data = (
|
|
28
|
+
# response.json()
|
|
29
|
+
# if response.data
|
|
30
|
+
# else {"message": f"HTTP {response.status}"}
|
|
31
|
+
# )
|
|
32
|
+
# error_message = error_data.get("message", str(error_data))
|
|
33
|
+
# raise urllib3.exceptions.HTTPError(error_message)
|
|
34
|
+
# return response.json()
|
|
35
|
+
# except urllib3.exceptions.HTTPError as e:
|
|
36
|
+
# return {"error": str(e)}
|
|
37
|
+
|
|
38
|
+
def _request(self, method, endpoint, payload=None, headers=None, form_data=None, **kwargs):
|
|
15
39
|
url = self.base_url + endpoint
|
|
16
40
|
request_headers = {
|
|
17
|
-
"Accept-Encoding": "gzip",
|
|
41
|
+
"Accept-Encoding": "gzip",
|
|
18
42
|
**self.headers,
|
|
19
43
|
}
|
|
20
44
|
if headers:
|
|
21
45
|
request_headers.update(headers)
|
|
22
46
|
|
|
23
47
|
try:
|
|
24
|
-
|
|
48
|
+
if form_data:
|
|
49
|
+
# Handle multipart form data
|
|
50
|
+
fields = {}
|
|
51
|
+
for key, value in form_data.items():
|
|
52
|
+
if isinstance(value, tuple):
|
|
53
|
+
# Handle file upload tuple (filename, content, content_type)
|
|
54
|
+
filename, file_data, content_type = value
|
|
55
|
+
fields[key] = (filename, file_data, content_type)
|
|
56
|
+
else:
|
|
57
|
+
fields[key] = value
|
|
58
|
+
|
|
59
|
+
response = self.http.request(
|
|
60
|
+
method,
|
|
61
|
+
url,
|
|
62
|
+
headers=request_headers,
|
|
63
|
+
fields=fields,
|
|
64
|
+
**kwargs
|
|
65
|
+
)
|
|
66
|
+
else:
|
|
67
|
+
response = self.http.request(
|
|
68
|
+
method,
|
|
69
|
+
url,
|
|
70
|
+
headers=request_headers,
|
|
71
|
+
**kwargs
|
|
72
|
+
)
|
|
25
73
|
|
|
26
74
|
if response.status >= 400:
|
|
27
75
|
error_data = (
|
|
@@ -34,3 +82,4 @@ class BaseClient:
|
|
|
34
82
|
return response.json()
|
|
35
83
|
except urllib3.exceptions.HTTPError as e:
|
|
36
84
|
return {"error": str(e)}
|
|
85
|
+
|
enkryptai_sdk/coc.py
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import os
|
|
2
|
+
# import requests
|
|
3
|
+
from .base import BaseClient
|
|
4
|
+
from .dto import (
|
|
5
|
+
CoCPolicyData,
|
|
6
|
+
CoCPolicyResponse,
|
|
7
|
+
CoCDeletePolicyResponse,
|
|
8
|
+
CoCListPoliciesResponse,
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class CoCClientError(Exception):
|
|
13
|
+
"""
|
|
14
|
+
A custom exception for CoCClient errors.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
pass
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class CoCClient(BaseClient):
|
|
21
|
+
"""
|
|
22
|
+
A client for interacting with Enkrypt AI CoC API endpoints.
|
|
23
|
+
"""
|
|
24
|
+
def __init__(self, api_key: str, base_url: str = "https://api.enkryptai.com:443"):
|
|
25
|
+
super().__init__(api_key, base_url)
|
|
26
|
+
|
|
27
|
+
def add_policy(self, policy_name, policy_rules=None, total_rules=None, policy_file=None, policy_text=None):
|
|
28
|
+
"""
|
|
29
|
+
Create a new policy with policy_rules.
|
|
30
|
+
|
|
31
|
+
Parameters:
|
|
32
|
+
- policy_name (str): Name of the policy
|
|
33
|
+
- policy_rules (List or Str): List of rules for the policy
|
|
34
|
+
- total_rules (int): Total number of rules
|
|
35
|
+
- policy_file (str, optional): Path to the policy file (PDF)
|
|
36
|
+
- policy_text (str, optional): Policy text content
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
- CoCPolicyResponse
|
|
40
|
+
|
|
41
|
+
Raises:
|
|
42
|
+
- CoCClientError: If validation fails or API returns an error
|
|
43
|
+
"""
|
|
44
|
+
try:
|
|
45
|
+
if not policy_file and not policy_text:
|
|
46
|
+
raise CoCClientError("Must provide either policy_file or policy_text")
|
|
47
|
+
if policy_file and policy_text:
|
|
48
|
+
raise CoCClientError("Cannot provide both policy_file and policy_text")
|
|
49
|
+
|
|
50
|
+
if isinstance(policy_rules, list):
|
|
51
|
+
policy_rules = "\n".join(policy_rules)
|
|
52
|
+
elif isinstance(policy_rules, str):
|
|
53
|
+
policy_rules = policy_rules.strip()
|
|
54
|
+
else:
|
|
55
|
+
raise CoCClientError("policy_rules must be a string or list of strings")
|
|
56
|
+
|
|
57
|
+
form_data = {
|
|
58
|
+
'name': policy_name,
|
|
59
|
+
'policy_rules': policy_rules,
|
|
60
|
+
'total_rules': total_rules
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if policy_file:
|
|
64
|
+
# Normalize file path and check existence
|
|
65
|
+
file_path = os.path.abspath(policy_file)
|
|
66
|
+
file_name = os.path.basename(file_path)
|
|
67
|
+
|
|
68
|
+
if not os.path.exists(file_path):
|
|
69
|
+
raise CoCClientError(f"File not found: {file_path}")
|
|
70
|
+
|
|
71
|
+
# Check file extension
|
|
72
|
+
if not file_path.lower().endswith('.pdf'):
|
|
73
|
+
raise CoCClientError("Only PDF files are supported")
|
|
74
|
+
|
|
75
|
+
with open(file_path, 'rb') as f:
|
|
76
|
+
file_content = f.read()
|
|
77
|
+
form_data['policy_file'] = (file_name, file_content, 'application/pdf')
|
|
78
|
+
else:
|
|
79
|
+
form_data['policy_text'] = policy_text
|
|
80
|
+
|
|
81
|
+
response = self._request(
|
|
82
|
+
"POST",
|
|
83
|
+
"/code-of-conduct/add-policy",
|
|
84
|
+
form_data=form_data
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
if isinstance(response, dict) and response.get("error"):
|
|
88
|
+
raise CoCClientError(f"API Error: {str(response)}")
|
|
89
|
+
|
|
90
|
+
return CoCPolicyResponse.from_dict(response)
|
|
91
|
+
except Exception as e:
|
|
92
|
+
raise CoCClientError(str(e))
|
|
93
|
+
|
|
94
|
+
def get_policy(self, policy_name):
|
|
95
|
+
"""
|
|
96
|
+
Retrieve an existing policy by providing its header identifier.
|
|
97
|
+
"""
|
|
98
|
+
headers = {"X-Enkrypt-Policy": policy_name}
|
|
99
|
+
|
|
100
|
+
try:
|
|
101
|
+
response = self._request("GET", "/code-of-conduct/get-policy", headers=headers)
|
|
102
|
+
if response.get("error"):
|
|
103
|
+
raise CoCClientError(f"API Error: {str(response)}")
|
|
104
|
+
return CoCPolicyData.from_dict(response)
|
|
105
|
+
except Exception as e:
|
|
106
|
+
raise CoCClientError(str(e))
|
|
107
|
+
|
|
108
|
+
def modify_policy(self, policy_name, policy_rules=None, total_rules=None, policy_file=None, policy_text=None):
|
|
109
|
+
"""
|
|
110
|
+
Modify a policy with policy_rules.
|
|
111
|
+
|
|
112
|
+
Parameters:
|
|
113
|
+
- policy_name (str): Name of the policy
|
|
114
|
+
- policy_rules (List or Str): List of rules for the policy
|
|
115
|
+
- total_rules (int): Total number of rules
|
|
116
|
+
- policy_file (str, optional): Path to the policy file (PDF)
|
|
117
|
+
- policy_text (str, optional): Policy text content
|
|
118
|
+
|
|
119
|
+
Returns:
|
|
120
|
+
- CoCPolicyResponse
|
|
121
|
+
|
|
122
|
+
Raises:
|
|
123
|
+
- CoCClientError: If validation fails or API returns an error
|
|
124
|
+
"""
|
|
125
|
+
try:
|
|
126
|
+
if not policy_file and not policy_text:
|
|
127
|
+
raise CoCClientError("Must provide either policy_file or policy_text")
|
|
128
|
+
if policy_file and policy_text:
|
|
129
|
+
raise CoCClientError("Cannot provide both policy_file and policy_text")
|
|
130
|
+
|
|
131
|
+
if isinstance(policy_rules, list):
|
|
132
|
+
policy_rules = "\n".join(policy_rules)
|
|
133
|
+
elif isinstance(policy_rules, str):
|
|
134
|
+
policy_rules = policy_rules.strip()
|
|
135
|
+
else:
|
|
136
|
+
raise CoCClientError("policy_rules must be a string or list of strings")
|
|
137
|
+
|
|
138
|
+
form_data = {
|
|
139
|
+
'name': policy_name,
|
|
140
|
+
'policy_rules': policy_rules,
|
|
141
|
+
'total_rules': total_rules
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if policy_file:
|
|
145
|
+
# Normalize file path and check existence
|
|
146
|
+
file_path = os.path.abspath(policy_file)
|
|
147
|
+
file_name = os.path.basename(file_path)
|
|
148
|
+
|
|
149
|
+
if not os.path.exists(file_path):
|
|
150
|
+
raise CoCClientError(f"File not found: {file_path}")
|
|
151
|
+
|
|
152
|
+
# Check file extension
|
|
153
|
+
if not file_path.lower().endswith('.pdf'):
|
|
154
|
+
raise CoCClientError("Only PDF files are supported")
|
|
155
|
+
|
|
156
|
+
with open(file_path, 'rb') as f:
|
|
157
|
+
file_content = f.read()
|
|
158
|
+
form_data['policy_file'] = (file_name, file_content, 'application/pdf')
|
|
159
|
+
else:
|
|
160
|
+
form_data['policy_text'] = policy_text
|
|
161
|
+
|
|
162
|
+
headers = {"X-Enkrypt-Policy": policy_name}
|
|
163
|
+
|
|
164
|
+
response = self._request(
|
|
165
|
+
"PATCH",
|
|
166
|
+
"/code-of-conduct/modify-policy",
|
|
167
|
+
form_data=form_data,
|
|
168
|
+
headers=headers
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
if isinstance(response, dict) and response.get("error"):
|
|
172
|
+
raise CoCClientError(f"API Error: {str(response)}")
|
|
173
|
+
|
|
174
|
+
return CoCPolicyResponse.from_dict(response)
|
|
175
|
+
except Exception as e:
|
|
176
|
+
raise CoCClientError(str(e))
|
|
177
|
+
|
|
178
|
+
def delete_policy(self, policy_name):
|
|
179
|
+
"""
|
|
180
|
+
Delete a policy.
|
|
181
|
+
"""
|
|
182
|
+
headers = {"X-Enkrypt-Policy": policy_name}
|
|
183
|
+
|
|
184
|
+
try:
|
|
185
|
+
response = self._request("DELETE", "/code-of-conduct/delete-policy", headers=headers)
|
|
186
|
+
if response.get("error"):
|
|
187
|
+
raise CoCClientError(f"API Error: {str(response)}")
|
|
188
|
+
return CoCDeletePolicyResponse.from_dict(response)
|
|
189
|
+
except Exception as e:
|
|
190
|
+
raise CoCClientError(str(e))
|
|
191
|
+
|
|
192
|
+
def get_policy_list(self):
|
|
193
|
+
"""
|
|
194
|
+
List all policies.
|
|
195
|
+
"""
|
|
196
|
+
|
|
197
|
+
try:
|
|
198
|
+
response = self._request("GET", "/code-of-conduct/list-policies")
|
|
199
|
+
if isinstance(response, dict) and response.get("error"):
|
|
200
|
+
raise CoCClientError(f"API Error: {str(response)}")
|
|
201
|
+
return CoCListPoliciesResponse.from_dict(response)
|
|
202
|
+
except Exception as e:
|
|
203
|
+
raise CoCClientError(str(e))
|
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
|
@@ -4,6 +4,7 @@ from .datasets import *
|
|
|
4
4
|
from .deployments import *
|
|
5
5
|
from .ai_proxy import *
|
|
6
6
|
from .guardrails import *
|
|
7
|
+
from .coc import *
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
__all__ = [
|
|
@@ -22,6 +23,8 @@ __all__ = [
|
|
|
22
23
|
"Metadata",
|
|
23
24
|
"DEFAULT_REDTEAM_CONFIG",
|
|
24
25
|
"DEFAULT_REDTEAM_CONFIG_WITH_SAVED_MODEL",
|
|
26
|
+
"DEFAULT_CUSTOM_REDTEAM_CONFIG",
|
|
27
|
+
"DEFAULT_CUSTOM_REDTEAM_CONFIG_WITH_SAVED_MODEL",
|
|
25
28
|
"ADVANCED_REDTEAM_TESTS",
|
|
26
29
|
"DETAIL_MODEL_CONFIG",
|
|
27
30
|
"DatasetConfig",
|
|
@@ -79,8 +82,16 @@ __all__ = [
|
|
|
79
82
|
"GuardrailsRelevancyResponse",
|
|
80
83
|
"GuardrailsPolicyRequest",
|
|
81
84
|
"GuardrailsPolicyData",
|
|
82
|
-
"
|
|
85
|
+
"GuardrailsPolicyResponse",
|
|
83
86
|
"GuardrailsDeletePolicyData",
|
|
84
87
|
"GuardrailsDeletePolicyResponse",
|
|
85
88
|
"GuardrailsListPoliciesResponse",
|
|
89
|
+
"GuardrailsPolicyAtomizerRequest",
|
|
90
|
+
"GuardrailsPolicyAtomizerResponse",
|
|
91
|
+
"CoCPolicyRequest",
|
|
92
|
+
"CoCPolicyData",
|
|
93
|
+
"CoCPolicyResponse",
|
|
94
|
+
"CoCDeletePolicyData",
|
|
95
|
+
"CoCDeletePolicyResponse",
|
|
96
|
+
"CoCListPoliciesResponse",
|
|
86
97
|
]
|
enkryptai_sdk/dto/coc.py
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
from .base import BaseDTO
|
|
3
|
+
from dataclasses import dataclass, field
|
|
4
|
+
from typing import List, Dict, Any, Set, Optional, BinaryIO
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@dataclass
|
|
8
|
+
class CoCPolicyData(BaseDTO):
|
|
9
|
+
created_at: str
|
|
10
|
+
name: str
|
|
11
|
+
updated_at: str
|
|
12
|
+
policy_id: int
|
|
13
|
+
project_name: str = "default"
|
|
14
|
+
policy_rules: str = ""
|
|
15
|
+
total_rules: int = 0
|
|
16
|
+
pdf_name: str = ""
|
|
17
|
+
_extra_fields: Dict[str, Any] = field(default_factory=dict)
|
|
18
|
+
|
|
19
|
+
@classmethod
|
|
20
|
+
def from_dict(cls, data: Dict[str, Any]) -> "CoCPolicyData":
|
|
21
|
+
return cls(
|
|
22
|
+
created_at=data.get("created_at", ""),
|
|
23
|
+
name=data.get("name", ""),
|
|
24
|
+
updated_at=data.get("updated_at", ""),
|
|
25
|
+
policy_id=data.get("policy_id", 0),
|
|
26
|
+
project_name=data.get("project_name", "default"),
|
|
27
|
+
policy_rules=data.get("policy_rules", ""),
|
|
28
|
+
total_rules=data.get("total_rules", 0),
|
|
29
|
+
pdf_name=data.get("pdf_name", "")
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
33
|
+
result = {
|
|
34
|
+
"created_at": self.created_at,
|
|
35
|
+
"name": self.name,
|
|
36
|
+
"updated_at": self.updated_at,
|
|
37
|
+
"policy_id": self.policy_id,
|
|
38
|
+
"project_name": self.project_name,
|
|
39
|
+
"policy_rules": self.policy_rules,
|
|
40
|
+
"total_rules": self.total_rules,
|
|
41
|
+
"pdf_name": self.pdf_name
|
|
42
|
+
}
|
|
43
|
+
result.update(self._extra_fields)
|
|
44
|
+
return result
|
|
45
|
+
|
|
46
|
+
def get_rules_list(self) -> List[str]:
|
|
47
|
+
"""
|
|
48
|
+
Get the policy rules as a list of strings.
|
|
49
|
+
|
|
50
|
+
Returns:
|
|
51
|
+
List[str]: List of individual policy rules
|
|
52
|
+
"""
|
|
53
|
+
if not self.policy_rules:
|
|
54
|
+
return []
|
|
55
|
+
return [rule.strip() for rule in self.policy_rules.split('\n') if rule.strip()]
|
|
56
|
+
|
|
57
|
+
def __str__(self) -> str:
|
|
58
|
+
"""
|
|
59
|
+
String representation of the response.
|
|
60
|
+
|
|
61
|
+
Returns:
|
|
62
|
+
str: A formatted string
|
|
63
|
+
"""
|
|
64
|
+
return (
|
|
65
|
+
f"Policy Name: {self.name}\n"
|
|
66
|
+
f"Created At: {self.created_at}\n"
|
|
67
|
+
f"Updated At: {self.updated_at}\n"
|
|
68
|
+
f"Policy ID: {self.policy_id}\n"
|
|
69
|
+
f"total_rules: {self.total_rules}\n"
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
@dataclass
|
|
74
|
+
class CoCPolicyResponse(BaseDTO):
|
|
75
|
+
message: str
|
|
76
|
+
data: CoCPolicyData
|
|
77
|
+
_extra_fields: Dict[str, Any] = field(default_factory=dict)
|
|
78
|
+
|
|
79
|
+
@classmethod
|
|
80
|
+
def from_dict(cls, data: Dict[str, Any]) -> "CoCPolicyResponse":
|
|
81
|
+
policy_data = data.get("data", {})
|
|
82
|
+
return cls(
|
|
83
|
+
message=data.get("message", ""),
|
|
84
|
+
data=CoCPolicyData.from_dict(policy_data)
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
88
|
+
result = {
|
|
89
|
+
"message": self.message,
|
|
90
|
+
"data": self.data.to_dict()
|
|
91
|
+
}
|
|
92
|
+
result.update(self._extra_fields)
|
|
93
|
+
return result
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
@dataclass
|
|
97
|
+
class CoCDeletePolicyData(BaseDTO):
|
|
98
|
+
policy_id: int
|
|
99
|
+
project_name: str = ""
|
|
100
|
+
_extra_fields: Dict[str, Any] = field(default_factory=dict)
|
|
101
|
+
|
|
102
|
+
@classmethod
|
|
103
|
+
def from_dict(cls, data: Dict[str, Any]) -> "CoCDeletePolicyData":
|
|
104
|
+
return cls(
|
|
105
|
+
policy_id=data.get("policy_id", 0),
|
|
106
|
+
project_name=data.get("project_name", "")
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
110
|
+
result = {
|
|
111
|
+
"policy_id": self.policy_id,
|
|
112
|
+
"project_name": self.project
|
|
113
|
+
}
|
|
114
|
+
result.update(self._extra_fields)
|
|
115
|
+
return result
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
@dataclass
|
|
119
|
+
class CoCDeletePolicyResponse(BaseDTO):
|
|
120
|
+
message: str
|
|
121
|
+
data: CoCDeletePolicyData
|
|
122
|
+
_extra_fields: Dict[str, Any] = field(default_factory=dict)
|
|
123
|
+
|
|
124
|
+
@classmethod
|
|
125
|
+
def from_dict(cls, data: Dict[str, Any]) -> "CoCDeletePolicyResponse":
|
|
126
|
+
policy_data = data.get("data", {})
|
|
127
|
+
return cls(
|
|
128
|
+
message=data.get("message", ""),
|
|
129
|
+
data=CoCDeletePolicyData.from_dict(policy_data)
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
133
|
+
result = {
|
|
134
|
+
"message": self.message,
|
|
135
|
+
"data": self.data.to_dict()
|
|
136
|
+
}
|
|
137
|
+
result.update(self._extra_fields)
|
|
138
|
+
return result
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
@dataclass
|
|
142
|
+
class CoCListPoliciesResponse(BaseDTO):
|
|
143
|
+
policies: List[CoCPolicyData] = field(default_factory=list)
|
|
144
|
+
_extra_fields: Dict[str, Any] = field(default_factory=dict)
|
|
145
|
+
|
|
146
|
+
@classmethod
|
|
147
|
+
def from_dict(cls, data: Dict[str, Any]) -> "CoCListPoliciesResponse":
|
|
148
|
+
policies_data = data.get("policies", [])
|
|
149
|
+
return cls(
|
|
150
|
+
policies=[CoCPolicyData.from_dict(policy) for policy in policies_data]
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
def to_dict(self) -> Dict[str, Any]:
|
|
154
|
+
result = {
|
|
155
|
+
"policies": [policy.to_dict() for policy in self.policies]
|
|
156
|
+
}
|
|
157
|
+
result.update(self._extra_fields)
|
|
158
|
+
return result
|
|
159
|
+
|