enkryptai-sdk 1.0.26__py3-none-any.whl → 1.0.27__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.
@@ -97,6 +97,7 @@ __all__ = [
97
97
  "GuardrailsListPoliciesResponse",
98
98
  "GuardrailsPolicyAtomizerRequest",
99
99
  "GuardrailsPolicyAtomizerResponse",
100
+ "GuardrailsScanPdfResponse",
100
101
  "CoCPolicyRequest",
101
102
  "CoCPolicyData",
102
103
  "CoCPolicyResponse",
@@ -1751,3 +1751,79 @@ class GuardrailsScanUrlResponse(BaseDTO):
1751
1751
 
1752
1752
  return f"URL Scan Result for {self.url}\nStatus: {status}\n{violation_str}"
1753
1753
 
1754
+
1755
+ # -------------------------------------
1756
+ # Guardrails Scan PDF
1757
+ # -------------------------------------
1758
+
1759
+
1760
+ @dataclass
1761
+ class ScanPdfDetails(BaseDTO):
1762
+ total_pages: int = 0
1763
+ pages_with_detections: int = 0
1764
+ detections: List[Dict[str, Any]] = field(default_factory=list)
1765
+ _extra_fields: Dict[str, Any] = field(default_factory=dict)
1766
+
1767
+ @classmethod
1768
+ def from_dict(cls, data: Dict[str, Any]) -> "ScanPdfDetails":
1769
+ return cls(
1770
+ total_pages=data.get("total_pages", 0),
1771
+ pages_with_detections=data.get("pages_with_detections", 0),
1772
+ detections=data.get("detections", [])
1773
+ )
1774
+
1775
+ def to_dict(self) -> Dict[str, Any]:
1776
+ result = {
1777
+ "total_pages": self.total_pages,
1778
+ "pages_with_detections": self.pages_with_detections,
1779
+ "detections": self.detections
1780
+ }
1781
+ result.update(self._extra_fields)
1782
+ return result
1783
+
1784
+
1785
+ @dataclass
1786
+ class GuardrailsScanPdfResponse(BaseDTO):
1787
+ summary: Dict[str, int] = field(default_factory=dict)
1788
+ details: ScanPdfDetails = field(default_factory=ScanPdfDetails)
1789
+ _extra_fields: Dict[str, Any] = field(default_factory=dict)
1790
+
1791
+ @classmethod
1792
+ def from_dict(cls, data: Dict[str, Any]) -> "GuardrailsScanPdfResponse":
1793
+ return cls(
1794
+ summary=data.get("summary", {}),
1795
+ details=ScanPdfDetails.from_dict(data.get("details", {}))
1796
+ )
1797
+
1798
+ def to_dict(self) -> Dict[str, Any]:
1799
+ result = {
1800
+ "summary": self.summary,
1801
+ "details": self.details.to_dict()
1802
+ }
1803
+ result.update(self._extra_fields)
1804
+ return result
1805
+
1806
+ def has_detections(self) -> bool:
1807
+ return self.details.pages_with_detections > 0 or len(self.details.detections) > 0
1808
+
1809
+ def is_safe(self) -> bool:
1810
+ return not self.has_detections()
1811
+
1812
+ def is_attack(self) -> bool:
1813
+ return self.has_detections()
1814
+
1815
+ def __str__(self) -> str:
1816
+ status = "UNSAFE" if self.has_detections() else "SAFE"
1817
+ flagged = [k for k, v in self.summary.items() if v > 0]
1818
+ if flagged:
1819
+ detection_str = f"Detections: {', '.join(flagged)}"
1820
+ else:
1821
+ detection_str = "No detections"
1822
+ return (
1823
+ f"PDF Scan Result\n"
1824
+ f"Status: {status}\n"
1825
+ f"Total Pages: {self.details.total_pages}\n"
1826
+ f"Pages With Detections: {self.details.pages_with_detections}\n"
1827
+ f"{detection_str}"
1828
+ )
1829
+
@@ -31,7 +31,8 @@ from .dto import (
31
31
  GuardrailsListPoliciesResponse,
32
32
  GuardrailsPolicyAtomizerRequest,
33
33
  GuardrailsPolicyAtomizerResponse,
34
- GuardrailsScanUrlResponse
34
+ GuardrailsScanUrlResponse,
35
+ GuardrailsScanPdfResponse
35
36
  )
36
37
 
37
38
  # ---------------------------------------
@@ -292,16 +293,20 @@ class GuardrailsClient(BaseClient):
292
293
 
293
294
  def scan_url(self, url, config=None):
294
295
  """
295
- Scan a URL for security threats including injection attacks and policy violations.
296
+ Scan a URL for security threats using any combination of available detectors.
297
+
298
+ Supports all detectors available in the detect endpoint, including:
299
+ injection_attack, policy_violation, toxicity, nsfw, pii, bias,
300
+ keyword_detector, copyright_ip, system_prompt, sponge_attack, topic_detector.
296
301
 
297
302
  Parameters:
298
303
  - url (str): The URL to scan and analyze.
299
304
  - config (dict or GuardrailsConfig, optional): A configuration for detectors.
300
- If a GuardrailsConfig instance is provided, its underlying dictionary will be used.
301
- If not provided, defaults to injection attack and policy violation detection.
305
+ If a GuardrailsConfig instance is provided, its underlying dictionary will be used.
306
+ If not provided, defaults to injection attack and policy violation detection.
302
307
 
303
308
  Returns:
304
- - Response from the API.
309
+ - GuardrailsScanUrlResponse: Response from the API containing scan results.
305
310
  """
306
311
  # Use default config if none provided
307
312
  if config is None:
@@ -358,6 +363,75 @@ class GuardrailsClient(BaseClient):
358
363
  except Exception as e:
359
364
  raise GuardrailsClientError(str(e))
360
365
 
366
+ def scan_pdf(self, file, config=None):
367
+ """
368
+ Scan a PDF for security threats using any combination of available detectors.
369
+
370
+ Supports all detectors available in the detect endpoint, including:
371
+ injection_attack, policy_violation, toxicity, nsfw, pii, bias,
372
+ keyword_detector, copyright_ip, system_prompt, sponge_attack, topic_detector.
373
+
374
+ Parameters:
375
+ - file (str): Base64-encoded PDF string.
376
+ - config (dict or GuardrailsConfig, optional): A configuration for detectors.
377
+ If a GuardrailsConfig instance is provided, its underlying dictionary will be used.
378
+ If not provided, defaults to injection attack and policy violation detection.
379
+
380
+ Returns:
381
+ - GuardrailsScanPdfResponse: Response from the API containing scan results.
382
+ """
383
+ if config is None:
384
+ config = {
385
+ "injection_attack": {
386
+ "enabled": True
387
+ },
388
+ "policy_violation": {
389
+ "enabled": True,
390
+ "policy_text": "Detect any malicious text or injection attacks",
391
+ "need_explanation": True
392
+ }
393
+ }
394
+
395
+ if hasattr(config, "as_dict"):
396
+ config = config.as_dict()
397
+ if hasattr(config, "to_dict"):
398
+ config = config.to_dict()
399
+
400
+ payload = {
401
+ "file": file,
402
+ "detectors": config
403
+ }
404
+
405
+ try:
406
+ response = self._request("POST", "/guardrails/scan-pdf", json=payload)
407
+ if response.get("error"):
408
+ raise GuardrailsClientError(f"API Error: {str(response)}")
409
+ return GuardrailsScanPdfResponse.from_dict(response)
410
+ except Exception as e:
411
+ raise GuardrailsClientError(str(e))
412
+
413
+ def policy_scan_pdf(self, policy_name, file):
414
+ """
415
+ Apply a specific policy to scan a PDF for security threats.
416
+
417
+ Parameters:
418
+ - policy_name (str): Name of the policy to apply.
419
+ - file (str): Base64-encoded PDF string.
420
+
421
+ Returns:
422
+ - GuardrailsScanPdfResponse: Response from the API containing scan results.
423
+ """
424
+ headers = {"X-Enkrypt-Policy": policy_name}
425
+ payload = {"file": file}
426
+
427
+ try:
428
+ response = self._request("POST", "/guardrails/policy/scan-pdf", headers=headers, json=payload)
429
+ if response.get("error"):
430
+ raise GuardrailsClientError(f"API Error: {str(response)}")
431
+ return GuardrailsScanPdfResponse.from_dict(response)
432
+ except Exception as e:
433
+ raise GuardrailsClientError(str(e))
434
+
361
435
  # ----------------------------
362
436
  # Guardrails Policy Endpoints
363
437
  # ----------------------------
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: enkryptai-sdk
3
- Version: 1.0.26
3
+ Version: 1.0.27
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
@@ -6,25 +6,25 @@ enkryptai_sdk/config.py,sha256=zUlWFr33JVz_kzUl3JalXeq-s1q0Qvyi4HBrGk0CTBU,9402
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
- enkryptai_sdk/guardrails.py,sha256=iEngSpkzZBB3EkJGxUxUgYF0Av4N2XWMN-BlAkRDle4,19856
9
+ enkryptai_sdk/guardrails.py,sha256=9lcc2PYH6PD3xvZ_SxQe4xU8WL2tXIfz1lLy0tLhsA0,22813
10
10
  enkryptai_sdk/guardrails_old.py,sha256=SgzPZkTzbAPD9XfmYNG6M1-TrzbhDHpAkI3FjnVWS_s,6434
11
11
  enkryptai_sdk/models.py,sha256=0R0I4KOq0aDNi5utabANot-E8dT9GqiSsgrcI9RULHM,8932
12
12
  enkryptai_sdk/red_team.py,sha256=3Fi2VE3slBEKU0_LCadMQm1Pm1Kp4Jx-MrwohqrqntM,28058
13
13
  enkryptai_sdk/response.py,sha256=2WOyejMYK7lA7I3fyebd0oYhP4js5Q1favJAV_h9pmo,13604
14
- enkryptai_sdk/dto/__init__.py,sha256=hBN523YIkuHCvLTrkPu9ipGwAyLDnhV9sb3rKNpRajg,3061
14
+ enkryptai_sdk/dto/__init__.py,sha256=tv3VxFetFGVR0vDE2oybh38qBDkAmvo4-FXXG_RkScY,3094
15
15
  enkryptai_sdk/dto/ai_proxy.py,sha256=clwMN4xdH8Zr55dnhilHbs-qaHRlCOrLPrij0Zd1Av0,11283
16
16
  enkryptai_sdk/dto/base.py,sha256=y77kQL1X7389ifSVNc0E7CUFNxACh5AM3ml9YPon1KY,2822
17
17
  enkryptai_sdk/dto/coc.py,sha256=9D5mmSdmC_guV75ml48PPLZD_zFa5FjxRwlTqHrmdak,5071
18
18
  enkryptai_sdk/dto/common.py,sha256=lrWMu4FKUGCN2dbS9fT4yNtfiPm1cNN16J4eCe4_tBM,1812
19
19
  enkryptai_sdk/dto/datasets.py,sha256=Ux72S2BoZ28-SpNA2C7P23W_wag6cvGvXvXeVHedvzk,7138
20
20
  enkryptai_sdk/dto/deployments.py,sha256=v--UrwkuXP4xTsPbmVruYj-g3JEQXepBRQfr-Gsv3aA,11744
21
- enkryptai_sdk/dto/guardrails.py,sha256=n73uPmK9fCIqqxv1rNecYUX4v5ePdIjxSBD4jIhwDe8,55966
21
+ enkryptai_sdk/dto/guardrails.py,sha256=_FWZ0AJOqw8tD75oajbv1FYyIrzJUN11dlMnb3X9sBE,58415
22
22
  enkryptai_sdk/dto/models.py,sha256=Dj9VBG7tWnNqnjyX2KMJXIlst-9Obzb_AtvbQiklizA,16632
23
23
  enkryptai_sdk/dto/red_team.py,sha256=_VR_L1fj4t0sKISaEoGxqUW3vA0lRAVMQejeFaQ70ho,40200
24
24
  enkryptai_sdk/utils/__init__.py,sha256=SII0dz9SesrXt2zOR1xXErPYZGj3WyC9A9Pn_eOLsOg,710
25
25
  enkryptai_sdk/utils/pagination.py,sha256=5t9qiDdxRA4uQywU4I4pp9OScqNBrEPmzKlPG-b-eVE,11149
26
- enkryptai_sdk-1.0.26.dist-info/licenses/LICENSE,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
- enkryptai_sdk-1.0.26.dist-info/METADATA,sha256=PTXLUL8KlDWw6uFL6-PCEMGNyK8rd5rp31LFJevFovY,1644
28
- enkryptai_sdk-1.0.26.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
29
- enkryptai_sdk-1.0.26.dist-info/top_level.txt,sha256=s2X9UJJwvJamNmr6ZXWyyQe60sXtQGWFuaBYfhgHI_4,14
30
- enkryptai_sdk-1.0.26.dist-info/RECORD,,
26
+ enkryptai_sdk-1.0.27.dist-info/licenses/LICENSE,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
+ enkryptai_sdk-1.0.27.dist-info/METADATA,sha256=h8lXBiColUVvV1G6KYxx8sNmxbjXYTBk-Xg-UX0rH8o,1644
28
+ enkryptai_sdk-1.0.27.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
29
+ enkryptai_sdk-1.0.27.dist-info/top_level.txt,sha256=s2X9UJJwvJamNmr6ZXWyyQe60sXtQGWFuaBYfhgHI_4,14
30
+ enkryptai_sdk-1.0.27.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5