enkryptai-sdk 1.0.9__py3-none-any.whl → 1.0.11__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/base.py CHANGED
@@ -72,14 +72,17 @@ class BaseClient:
72
72
  )
73
73
 
74
74
  if response.status >= 400:
75
- error_data = (
76
- response.json()
77
- if response.data
78
- else {"message": f"HTTP {response.status}"}
79
- )
80
- error_message = error_data.get("message", str(error_data))
75
+ try:
76
+ error_data = response.json()
77
+ error_message = error_data.get("message", str(error_data))
78
+ except:
79
+ error_message = response.data.decode('utf-8') if response.data else f"HTTP {response.status}"
81
80
  raise urllib3.exceptions.HTTPError(error_message)
82
- return response.json()
81
+
82
+ try:
83
+ return response.json()
84
+ except:
85
+ return {"error": response.data.decode('utf-8') if response.data else "Invalid JSON response"}
83
86
  except urllib3.exceptions.HTTPError as e:
84
87
  return {"error": str(e)}
85
88
 
enkryptai_sdk/config.py CHANGED
@@ -10,7 +10,7 @@ DEFAULT_GUARDRAILS_CONFIG = {
10
10
  "keyword_detector": {"enabled": False, "banned_keywords": []},
11
11
  "policy_violation": {
12
12
  "enabled": False,
13
- "policy_text": "",
13
+ "policy_text": "Do not allow any illegal or immoral activities.",
14
14
  "need_explanation": False,
15
15
  },
16
16
  "bias": {"enabled": False},
@@ -42,16 +42,21 @@ class GuardrailsConfig:
42
42
  return cls(config)
43
43
 
44
44
  @classmethod
45
- def policy_violation(cls, policy_text: str, need_explanation: bool = False):
45
+ def policy_violation(cls, policy_text: str = "", need_explanation: bool = False, coc_policy_name: str = ""):
46
46
  """
47
47
  Returns a configuration instance pre-configured for policy violation detection.
48
48
  """
49
49
  config = copy.deepcopy(DEFAULT_GUARDRAILS_CONFIG)
50
50
  config["policy_violation"] = {
51
51
  "enabled": True,
52
- "policy_text": policy_text,
53
52
  "need_explanation": need_explanation,
54
53
  }
54
+
55
+ if policy_text:
56
+ config["policy_violation"]["policy_text"] = policy_text
57
+ if coc_policy_name:
58
+ config["policy_violation"]["coc_policy_name"] = coc_policy_name
59
+
55
60
  return cls(config)
56
61
 
57
62
  @classmethod
enkryptai_sdk/dto/base.py CHANGED
@@ -52,7 +52,18 @@ class BaseDTO:
52
52
 
53
53
  def to_dict(self) -> Dict[str, Any]:
54
54
  """Convert the instance to a dictionary."""
55
- d = {k: v for k, v in self.__dict__.items() if k != "_extra_fields"}
55
+ d = {}
56
+ for k, v in self.__dict__.items():
57
+ if k == "_extra_fields":
58
+ continue
59
+ if hasattr(v, "to_dict"):
60
+ d[k] = v.to_dict()
61
+ elif isinstance(v, list):
62
+ d[k] = [item.to_dict() if hasattr(item, "to_dict") else item for item in v]
63
+ elif isinstance(v, dict):
64
+ d[k] = {key: val.to_dict() if hasattr(val, "to_dict") else val for key, val in v.items()}
65
+ else:
66
+ d[k] = v
56
67
  d.update(self._extra_fields)
57
68
  return d
58
69
 
@@ -163,6 +163,7 @@ class PolicyViolationDetector(BaseDTO):
163
163
  enabled: bool = False
164
164
  policy_text: str = ""
165
165
  need_explanation: bool = False
166
+ coc_policy_name: str = ""
166
167
  _extra_fields: Dict[str, Any] = field(default_factory=dict)
167
168
 
168
169
  @classmethod
@@ -170,16 +171,23 @@ class PolicyViolationDetector(BaseDTO):
170
171
  return cls(
171
172
  enabled=data.get("enabled", False),
172
173
  policy_text=data.get("policy_text", ""),
173
- need_explanation=data.get("need_explanation", False)
174
+ need_explanation=data.get("need_explanation", False),
175
+ coc_policy_name=data.get("coc_policy_name", "")
174
176
  )
175
177
 
176
178
  def to_dict(self) -> Dict[str, Any]:
177
- return {
179
+ res_dict = {
178
180
  "enabled": self.enabled,
179
- "policy_text": self.policy_text,
180
181
  "need_explanation": self.need_explanation
181
182
  }
182
183
 
184
+ if self.policy_text:
185
+ res_dict["policy_text"] = self.policy_text
186
+ if self.coc_policy_name:
187
+ res_dict["coc_policy_name"] = self.coc_policy_name
188
+
189
+ return res_dict
190
+
183
191
 
184
192
  @dataclass
185
193
  class BiasDetector(BaseDTO):
@@ -37,6 +37,8 @@ class ModelProviders(str, Enum):
37
37
  OPENAI_COMPATIBLE = "openai_compatible"
38
38
  COHERE_COMPATIBLE = "cohere_compatible"
39
39
  ANTHROPIC_COMPATIBLE = "anthropic_compatible"
40
+ CUSTOM = "custom"
41
+ HR = "hr"
40
42
 
41
43
 
42
44
  @dataclass
@@ -247,6 +249,14 @@ class ModelConfigDetails(BaseDTO):
247
249
  d = super().to_dict()
248
250
  # Handle AuthData specifically
249
251
  d["auth_data"] = self.auth_data.to_dict()
252
+ # Handle CustomHeader list
253
+ d["custom_headers"] = [header.to_dict() for header in self.custom_headers]
254
+ # Handle ModelProviders enum
255
+ if isinstance(d["model_provider"], ModelProviders):
256
+ d["model_provider"] = d["model_provider"].value
257
+ # Handle input/output modalities
258
+ d["input_modalities"] = [m.value for m in self.input_modalities]
259
+ d["output_modalities"] = [m.value for m in self.output_modalities]
250
260
  return d
251
261
 
252
262
  def to_json(self):
@@ -289,6 +299,13 @@ class ModelConfig(BaseDTO):
289
299
 
290
300
  return cls(**data, model_config=model_config)
291
301
 
302
+ def to_dict(self) -> dict:
303
+ """Convert the ModelConfig instance to a dictionary."""
304
+ d = super().to_dict()
305
+ # Handle nested ModelConfigDetails
306
+ d["model_config"] = self.model_config.to_dict()
307
+ return d
308
+
292
309
  @classmethod
293
310
  def __str__(self):
294
311
  """String representation of the ModelConfig."""
@@ -367,7 +367,15 @@ class TargetModelConfiguration(BaseDTO):
367
367
 
368
368
  @classmethod
369
369
  def from_dict(cls, data: dict):
370
+ data = data.copy()
371
+ if "custom_headers" in data:
372
+ data["custom_headers"] = [CustomHeader.from_dict(header) for header in data["custom_headers"]]
370
373
  return cls(**data)
374
+
375
+ def to_dict(self) -> dict:
376
+ d = asdict(self)
377
+ d["custom_headers"] = [header.to_dict() for header in self.custom_headers]
378
+ return d
371
379
 
372
380
 
373
381
  @dataclass
enkryptai_sdk/models.py CHANGED
@@ -49,6 +49,9 @@ class ModelClient(BaseClient):
49
49
  "chat": f"/{remaining_path}" if remaining_path else "",
50
50
  }
51
51
 
52
+ # Convert custom_headers to list of dictionaries
53
+ custom_headers = [header.to_dict() for header in config.model_config.custom_headers]
54
+
52
55
  payload = {
53
56
  "testing_for": config.testing_for,
54
57
  "model_name": config.model_name,
@@ -72,9 +75,9 @@ class ModelClient(BaseClient):
72
75
  },
73
76
  "apikeys": [config.model_config.apikey] if config.model_config.apikey else [],
74
77
  "tools": config.model_config.tools,
75
- "input_modalities": config.model_config.input_modalities,
76
- "output_modalities": config.model_config.output_modalities,
77
- "custom_headers": config.model_config.custom_headers,
78
+ "input_modalities": [m.value if hasattr(m, 'value') else m for m in config.model_config.input_modalities],
79
+ "output_modalities": [m.value if hasattr(m, 'value') else m for m in config.model_config.output_modalities],
80
+ "custom_headers": custom_headers,
78
81
  "custom_payload": config.model_config.custom_payload,
79
82
  "custom_response_content_type": config.model_config.custom_response_content_type,
80
83
  "custom_response_format": config.model_config.custom_response_format,
@@ -189,6 +192,9 @@ class ModelClient(BaseClient):
189
192
  "chat": f"/{remaining_path}" if remaining_path else "",
190
193
  }
191
194
 
195
+ # Convert custom_headers to list of dictionaries
196
+ custom_headers = [header.to_dict() for header in config.model_config.custom_headers]
197
+
192
198
  payload = {
193
199
  "model_saved_name": config.model_saved_name,
194
200
  "model_version": config.model_version,
@@ -217,9 +223,9 @@ class ModelClient(BaseClient):
217
223
  [config.model_config.apikey] if config.model_config.apikey else []
218
224
  ),
219
225
  "tools": config.model_config.tools,
220
- "input_modalities": config.model_config.input_modalities,
221
- "output_modalities": config.model_config.output_modalities,
222
- "custom_headers": config.model_config.custom_headers,
226
+ "input_modalities": [m.value if hasattr(m, 'value') else m for m in config.model_config.input_modalities],
227
+ "output_modalities": [m.value if hasattr(m, 'value') else m for m in config.model_config.output_modalities],
228
+ "custom_headers": custom_headers,
223
229
  "custom_payload": config.model_config.custom_payload,
224
230
  "custom_response_content_type": config.model_config.custom_response_content_type,
225
231
  "custom_response_format": config.model_config.custom_response_format,
enkryptai_sdk/red_team.py CHANGED
@@ -1,4 +1,5 @@
1
- import urllib3
1
+ # import json
2
+ # import urllib3
2
3
  from .base import BaseClient
3
4
  from .models import ModelClient
4
5
  from .datasets import DatasetClient
@@ -62,6 +63,8 @@ class RedTeamClient(BaseClient):
62
63
  """
63
64
  try:
64
65
  config = RedTeamModelHealthConfig.from_dict(config)
66
+ # Print the config as json string
67
+ # print(f"Config: {json.dumps(config.to_dict(), indent=4)}")
65
68
  response = self._request("POST", "/redteam/model-health", json=config.to_dict())
66
69
  # if response.get("error"):
67
70
  if response.get("error") not in [None, ""]:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: enkryptai-sdk
3
- Version: 1.0.9
3
+ Version: 1.0.11
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
@@ -264,7 +264,10 @@ sample_detectors = {
264
264
  "policy_violation": {
265
265
  "enabled": True,
266
266
  "need_explanation": True,
267
- "policy_text": ""
267
+ "policy_text": "The model should not provide medical advice when asked about health symptoms."
268
+ # Or we can also give coc_policy_name of a saved Code of Conduct Policy
269
+ # Instead of policy_text
270
+ # "coc_policy_name": "Test CoC Policy"
268
271
  },
269
272
  "bias": {
270
273
  "enabled": False
@@ -718,6 +721,9 @@ guardrails_config = GuardrailsConfig.injection_attack()
718
721
 
719
722
  ```python Python
720
723
  guardrails_config = GuardrailsConfig.policy_violation(policy_text="You must not use hate speech", need_explanation=True)
724
+
725
+ # Or we can also give coc_policy_name of a saved Code of Conduct Policy instead of policy_text
726
+ guardrails_config = GuardrailsConfig.policy_violation(coc_policy_name="Test CoC Policy", need_explanation=True)
721
727
  ```
722
728
 
723
729
  ### [Toxicity](https://docs.enkryptai.com/guardrails-api-reference/Toxicity_Detector)
@@ -1,27 +1,27 @@
1
1
  enkryptai_sdk/__init__.py,sha256=8H5tznmjirTVdrTmrsyU6fNVRj3-UC0nrTGkzfFp0h0,845
2
2
  enkryptai_sdk/ai_proxy.py,sha256=ot1lqKk2LjcvlpnFm2kSA51vFThfquVlx86BhSbAzBo,3823
3
- enkryptai_sdk/base.py,sha256=8iQr5skm46-hGFIMOZsQgZkqL0RBrIJDYUENOybBrwg,3087
3
+ enkryptai_sdk/base.py,sha256=KonezvdjVzIr3gw75grzcCNyhzI_sHXi-Cb9tRJgSDE,3277
4
4
  enkryptai_sdk/coc.py,sha256=5rq9LhZX-uvCmX8fM6JEndIEvd8rSzsSfDFnTvSvTQE,7396
5
- enkryptai_sdk/config.py,sha256=IpB8_aO4zXdvv061v24oh83oyJ5Tp1QBQTzeuW4h9QY,8828
5
+ enkryptai_sdk/config.py,sha256=PyyuJRKWuiuFUaI90M21M141wlfIBeO_QVDU36KHKCs,9065
6
6
  enkryptai_sdk/datasets.py,sha256=RQIR6spI2STXeVolYzBt6gPv6PD5AGh9krs16aKWdWA,6067
7
7
  enkryptai_sdk/deployments.py,sha256=A7XZ2JwrMod9V4_aV8bFY_Soh9E3jHdwaTuJ9BwXuyk,4215
8
8
  enkryptai_sdk/evals.py,sha256=BywyEgIT7xdJ58svO_sDNOMVowdB0RTGoAZPEbCnDVo,2595
9
9
  enkryptai_sdk/guardrails.py,sha256=NluimOA0gM9N3S_q47LTUeG97t9PlYqPHlZahDPkJvI,16365
10
10
  enkryptai_sdk/guardrails_old.py,sha256=SgzPZkTzbAPD9XfmYNG6M1-TrzbhDHpAkI3FjnVWS_s,6434
11
- enkryptai_sdk/models.py,sha256=2H316e28Ssi_MHck0pAoydThRYSdAeSOlwwAoU7q86Q,10941
12
- enkryptai_sdk/red_team.py,sha256=sJbhCuPfI9aowGvV71hRZslBp1HQa7bklbb89HU5tk8,18574
11
+ enkryptai_sdk/models.py,sha256=EA2jwdoYqOjQ8GuRawsZ3syIvVinwhvodTLQlvt51Mo,11399
12
+ enkryptai_sdk/red_team.py,sha256=iTBSXNUr_JFFQppKzUzJ5-gWtlPPzY6BkKahhXppaFM,18709
13
13
  enkryptai_sdk/response.py,sha256=43JRubzgGCpoVxYNzBZY0AlUgLbfcXD_AwD7wU3qY9o,4086
14
14
  enkryptai_sdk/dto/__init__.py,sha256=wHgIv_OCnVMJOys-vqImF59ifogDrMcgxVRmfNayVvc,2761
15
15
  enkryptai_sdk/dto/ai_proxy.py,sha256=clwMN4xdH8Zr55dnhilHbs-qaHRlCOrLPrij0Zd1Av0,11283
16
- enkryptai_sdk/dto/base.py,sha256=6VWTkoNZ7uILqn_iYsPS21cVa2xLYpw5bjDIsRCS5tk,2389
16
+ enkryptai_sdk/dto/base.py,sha256=y77kQL1X7389ifSVNc0E7CUFNxACh5AM3ml9YPon1KY,2822
17
17
  enkryptai_sdk/dto/coc.py,sha256=Lp2aat_24J4KuUg4BeJl9S39tEak8Bw15eJ4cQDrRQk,4749
18
18
  enkryptai_sdk/dto/datasets.py,sha256=RFA9CmbhD-QDDyweBq_k9iBd00b6I6SWmdP9DPNd9fc,5002
19
19
  enkryptai_sdk/dto/deployments.py,sha256=Aw4b8tDA3FYIomqDvCjblCXTagL4bT8Fx91X0SFXs40,11216
20
- enkryptai_sdk/dto/guardrails.py,sha256=7hWzhFH-tc6Rbwkl6ZzW_egWTvrLXv4K22M7dNbKQuE,49556
21
- enkryptai_sdk/dto/models.py,sha256=lNakMstGozgN_htY2_OItkjQnMQpw5tO9lCZVlywMIg,13442
22
- enkryptai_sdk/dto/red_team.py,sha256=QtsT4GCnDs24WOF_RMxFtYjvIUULaw5temZ70aduevI,17966
23
- enkryptai_sdk-1.0.9.dist-info/licenses/LICENSE,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
- enkryptai_sdk-1.0.9.dist-info/METADATA,sha256=GDQsqPQycozBDIOW3qCfq3wEzNBVPs_4XcmXg-V3kYo,61634
25
- enkryptai_sdk-1.0.9.dist-info/WHEEL,sha256=pxyMxgL8-pra_rKaQ4drOZAegBVuX-G_4nRHjjgWbmo,91
26
- enkryptai_sdk-1.0.9.dist-info/top_level.txt,sha256=s2X9UJJwvJamNmr6ZXWyyQe60sXtQGWFuaBYfhgHI_4,14
27
- enkryptai_sdk-1.0.9.dist-info/RECORD,,
20
+ enkryptai_sdk/dto/guardrails.py,sha256=wfKm2R0uJAq9nljLBPuuT05tj1nBqZraga-5lMHd3n8,49812
21
+ enkryptai_sdk/dto/models.py,sha256=08ilpQkp_tpUDzM5Jt-mrWdHlbBgYst0plzzT4G-Gds,14184
22
+ enkryptai_sdk/dto/red_team.py,sha256=UNqiPxKqk8TJ-hLtBCWRvtoXyGCFiz3X7bKpx8sTQxo,18298
23
+ enkryptai_sdk-1.0.11.dist-info/licenses/LICENSE,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
+ enkryptai_sdk-1.0.11.dist-info/METADATA,sha256=adej6oT0uO297qJIDmyktoTx7CmgSZWiBMyPWAHYMro,62092
25
+ enkryptai_sdk-1.0.11.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
26
+ enkryptai_sdk-1.0.11.dist-info/top_level.txt,sha256=s2X9UJJwvJamNmr6ZXWyyQe60sXtQGWFuaBYfhgHI_4,14
27
+ enkryptai_sdk-1.0.11.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (79.0.0)
2
+ Generator: setuptools (80.8.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5