enkryptai-sdk 1.0.26__tar.gz → 1.0.27__tar.gz

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.
Files changed (50) hide show
  1. {enkryptai_sdk-1.0.26 → enkryptai_sdk-1.0.27}/PKG-INFO +1 -1
  2. {enkryptai_sdk-1.0.26 → enkryptai_sdk-1.0.27}/setup.py +1 -1
  3. {enkryptai_sdk-1.0.26 → enkryptai_sdk-1.0.27}/src/enkryptai_sdk/dto/__init__.py +1 -0
  4. {enkryptai_sdk-1.0.26 → enkryptai_sdk-1.0.27}/src/enkryptai_sdk/dto/guardrails.py +76 -0
  5. {enkryptai_sdk-1.0.26 → enkryptai_sdk-1.0.27}/src/enkryptai_sdk/guardrails.py +79 -5
  6. {enkryptai_sdk-1.0.26 → enkryptai_sdk-1.0.27}/src/enkryptai_sdk.egg-info/PKG-INFO +1 -1
  7. {enkryptai_sdk-1.0.26 → enkryptai_sdk-1.0.27}/tests/test_all_v2.py +205 -171
  8. {enkryptai_sdk-1.0.26 → enkryptai_sdk-1.0.27}/LICENSE +0 -0
  9. {enkryptai_sdk-1.0.26 → enkryptai_sdk-1.0.27}/README.md +0 -0
  10. {enkryptai_sdk-1.0.26 → enkryptai_sdk-1.0.27}/setup.cfg +0 -0
  11. {enkryptai_sdk-1.0.26 → enkryptai_sdk-1.0.27}/src/enkryptai_sdk/__init__.py +0 -0
  12. {enkryptai_sdk-1.0.26 → enkryptai_sdk-1.0.27}/src/enkryptai_sdk/ai_proxy.py +0 -0
  13. {enkryptai_sdk-1.0.26 → enkryptai_sdk-1.0.27}/src/enkryptai_sdk/base.py +0 -0
  14. {enkryptai_sdk-1.0.26 → enkryptai_sdk-1.0.27}/src/enkryptai_sdk/coc.py +0 -0
  15. {enkryptai_sdk-1.0.26 → enkryptai_sdk-1.0.27}/src/enkryptai_sdk/config.py +0 -0
  16. {enkryptai_sdk-1.0.26 → enkryptai_sdk-1.0.27}/src/enkryptai_sdk/datasets.py +0 -0
  17. {enkryptai_sdk-1.0.26 → enkryptai_sdk-1.0.27}/src/enkryptai_sdk/deployments.py +0 -0
  18. {enkryptai_sdk-1.0.26 → enkryptai_sdk-1.0.27}/src/enkryptai_sdk/dto/ai_proxy.py +0 -0
  19. {enkryptai_sdk-1.0.26 → enkryptai_sdk-1.0.27}/src/enkryptai_sdk/dto/base.py +0 -0
  20. {enkryptai_sdk-1.0.26 → enkryptai_sdk-1.0.27}/src/enkryptai_sdk/dto/coc.py +0 -0
  21. {enkryptai_sdk-1.0.26 → enkryptai_sdk-1.0.27}/src/enkryptai_sdk/dto/common.py +0 -0
  22. {enkryptai_sdk-1.0.26 → enkryptai_sdk-1.0.27}/src/enkryptai_sdk/dto/datasets.py +0 -0
  23. {enkryptai_sdk-1.0.26 → enkryptai_sdk-1.0.27}/src/enkryptai_sdk/dto/deployments.py +0 -0
  24. {enkryptai_sdk-1.0.26 → enkryptai_sdk-1.0.27}/src/enkryptai_sdk/dto/models.py +0 -0
  25. {enkryptai_sdk-1.0.26 → enkryptai_sdk-1.0.27}/src/enkryptai_sdk/dto/red_team.py +0 -0
  26. {enkryptai_sdk-1.0.26 → enkryptai_sdk-1.0.27}/src/enkryptai_sdk/evals.py +0 -0
  27. {enkryptai_sdk-1.0.26 → enkryptai_sdk-1.0.27}/src/enkryptai_sdk/guardrails_old.py +0 -0
  28. {enkryptai_sdk-1.0.26 → enkryptai_sdk-1.0.27}/src/enkryptai_sdk/models.py +0 -0
  29. {enkryptai_sdk-1.0.26 → enkryptai_sdk-1.0.27}/src/enkryptai_sdk/red_team.py +0 -0
  30. {enkryptai_sdk-1.0.26 → enkryptai_sdk-1.0.27}/src/enkryptai_sdk/response.py +0 -0
  31. {enkryptai_sdk-1.0.26 → enkryptai_sdk-1.0.27}/src/enkryptai_sdk/utils/__init__.py +0 -0
  32. {enkryptai_sdk-1.0.26 → enkryptai_sdk-1.0.27}/src/enkryptai_sdk/utils/pagination.py +0 -0
  33. {enkryptai_sdk-1.0.26 → enkryptai_sdk-1.0.27}/src/enkryptai_sdk.egg-info/SOURCES.txt +0 -0
  34. {enkryptai_sdk-1.0.26 → enkryptai_sdk-1.0.27}/src/enkryptai_sdk.egg-info/dependency_links.txt +0 -0
  35. {enkryptai_sdk-1.0.26 → enkryptai_sdk-1.0.27}/src/enkryptai_sdk.egg-info/top_level.txt +0 -0
  36. {enkryptai_sdk-1.0.26 → enkryptai_sdk-1.0.27}/tests/test_ai_proxy.py +0 -0
  37. {enkryptai_sdk-1.0.26 → enkryptai_sdk-1.0.27}/tests/test_all.py +0 -0
  38. {enkryptai_sdk-1.0.26 → enkryptai_sdk-1.0.27}/tests/test_basic.py +0 -0
  39. {enkryptai_sdk-1.0.26 → enkryptai_sdk-1.0.27}/tests/test_boxai.py +0 -0
  40. {enkryptai_sdk-1.0.26 → enkryptai_sdk-1.0.27}/tests/test_coc.py +0 -0
  41. {enkryptai_sdk-1.0.26 → enkryptai_sdk-1.0.27}/tests/test_datasets.py +0 -0
  42. {enkryptai_sdk-1.0.26 → enkryptai_sdk-1.0.27}/tests/test_deployments.py +0 -0
  43. {enkryptai_sdk-1.0.26 → enkryptai_sdk-1.0.27}/tests/test_detect_policy.py +0 -0
  44. {enkryptai_sdk-1.0.26 → enkryptai_sdk-1.0.27}/tests/test_guardrails.py +0 -0
  45. {enkryptai_sdk-1.0.26 → enkryptai_sdk-1.0.27}/tests/test_injection_attack.py +0 -0
  46. {enkryptai_sdk-1.0.26 → enkryptai_sdk-1.0.27}/tests/test_model.py +0 -0
  47. {enkryptai_sdk-1.0.26 → enkryptai_sdk-1.0.27}/tests/test_openai.py +0 -0
  48. {enkryptai_sdk-1.0.26 → enkryptai_sdk-1.0.27}/tests/test_pagination.py +0 -0
  49. {enkryptai_sdk-1.0.26 → enkryptai_sdk-1.0.27}/tests/test_policy_violation.py +0 -0
  50. {enkryptai_sdk-1.0.26 → enkryptai_sdk-1.0.27}/tests/test_redteam.py +0 -0
@@ -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
@@ -9,7 +9,7 @@ with open(os.path.join(here, "README.md"), encoding="utf-8") as fh:
9
9
  setup(
10
10
  name="enkryptai-sdk", # This is the name of your package on PyPI
11
11
  # NOTE: Also change this in .github/workflows/test.yaml
12
- version="1.0.26", # Update this for new versions
12
+ version="1.0.27", # Update this for new versions
13
13
  description="A Python SDK with guardrails and red teaming functionality for API interactions",
14
14
  long_description=long_description,
15
15
  long_description_content_type="text/markdown",
@@ -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
@@ -2,7 +2,7 @@
2
2
 
3
3
  import os
4
4
  import time
5
- import uuid
5
+ # import uuid # Only used for dataset tests which are now commented out
6
6
  import pytest
7
7
  from fixtures import *
8
8
  from enkryptai_sdk import *
@@ -28,8 +28,8 @@ pii_de_anonymized_text = "My email is example@example.com. My phone number is 12
28
28
  pii_key = None
29
29
  pii_anonymized_text = None
30
30
 
31
- dataset_name = None
32
- picked_dataset_name = None
31
+ # dataset_name = None
32
+ # picked_dataset_name = None
33
33
 
34
34
  redteam_test_name = None
35
35
  redteam_model_test_name = None
@@ -85,10 +85,10 @@ def deployment_client():
85
85
  # You'll want to use a test API key here
86
86
  return DeploymentClient(api_key=ENKRYPT_API_KEY, base_url=ENKRYPT_BASE_URL)
87
87
 
88
- @pytest.fixture
89
- def dataset_client():
90
- # You'll want to use a test API key here
91
- return DatasetClient(api_key=ENKRYPT_API_KEY, base_url=ENKRYPT_BASE_URL)
88
+ # @pytest.fixture
89
+ # def dataset_client():
90
+ # # You'll want to use a test API key here
91
+ # return DatasetClient(api_key=ENKRYPT_API_KEY, base_url=ENKRYPT_BASE_URL)
92
92
 
93
93
  # Getting from fixtures.py
94
94
  # @pytest.fixture
@@ -250,29 +250,29 @@ def sample_deployment_config():
250
250
  },
251
251
  }
252
252
 
253
- @pytest.fixture
254
- def sample_dataset_config():
255
- print("\nCreating sample dataset config")
256
- global dataset_name
257
- dataset_name = f"TestElectionDataset-{str(uuid.uuid4())[:8]}"
258
- print("\nDataset Name: ", dataset_name)
259
- return {
260
- "dataset_name": dataset_name,
261
- # "dataset_name": "TestElectionDataset",
262
- "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.",
263
- "policy_description": "",
264
- "tools": [
265
- {
266
- "name": "web_search",
267
- "description": "The tool web search is used to search the web for information related to finance."
268
- }
269
- ],
270
- "info_pdf_url": "",
271
- "max_prompts": 100,
272
- "scenarios": 2,
273
- "categories": 2,
274
- "depth": 2,
275
- }
253
+ # @pytest.fixture
254
+ # def sample_dataset_config():
255
+ # print("\nCreating sample dataset config")
256
+ # global dataset_name
257
+ # dataset_name = f"TestElectionDataset-{str(uuid.uuid4())[:8]}"
258
+ # print("\nDataset Name: ", dataset_name)
259
+ # return {
260
+ # "dataset_name": dataset_name,
261
+ # # "dataset_name": "TestElectionDataset",
262
+ # "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.",
263
+ # "policy_description": "",
264
+ # "tools": [
265
+ # {
266
+ # "name": "web_search",
267
+ # "description": "The tool web search is used to search the web for information related to finance."
268
+ # }
269
+ # ],
270
+ # "info_pdf_url": "",
271
+ # "max_prompts": 100,
272
+ # "scenarios": 2,
273
+ # "categories": 2,
274
+ # "depth": 2,
275
+ # }
276
276
 
277
277
  # Getting Red team fixtures from fixtures.py
278
278
 
@@ -325,34 +325,34 @@ def get_task_name_from_list(redteam_client, status=None):
325
325
  return test_name
326
326
 
327
327
 
328
- def get_dataset_name_from_list(dataset_client, status=None):
329
- """Helper function to get a dataset name from the datasets list.
330
-
331
- Args:
332
- dataset_client: The DatasetClient instance
333
- status: Optional status filter (e.g., "Finished", "Running")
334
-
335
- Returns:
336
- str: A dataset name from the datasets list
337
- """
338
- print(f"\nFetching dataset with status: {status if status else 'Finished'}")
339
- datasets = dataset_client.list_datasets(status=status)
340
- datasets_dict = datasets.to_dict()
341
- print(f"\nDatasets list retrieved with {len(datasets_dict.get('datasets', []))} datasets")
342
-
343
- if not datasets_dict.get("datasets"):
344
- # If no datasets with specified status, try without status filter
345
- if status:
346
- print(f"\nNo datasets with status '{status}', fetching any dataset")
347
- datasets = dataset_client.list_datasets()
348
- datasets_dict = datasets.to_dict()
349
-
350
- if not datasets_dict.get("datasets"):
351
- return None
352
-
353
- dataset_name = datasets_dict["datasets"][0]
354
- print(f"\nSelected dataset: {dataset_name}")
355
- return dataset_name
328
+ # def get_dataset_name_from_list(dataset_client, status=None):
329
+ # """Helper function to get a dataset name from the datasets list.
330
+ #
331
+ # Args:
332
+ # dataset_client: The DatasetClient instance
333
+ # status: Optional status filter (e.g., "Finished", "Running")
334
+ #
335
+ # Returns:
336
+ # str: A dataset name from the datasets list
337
+ # """
338
+ # print(f"\nFetching dataset with status: {status if status else 'Finished'}")
339
+ # datasets = dataset_client.list_datasets(status=status)
340
+ # datasets_dict = datasets.to_dict()
341
+ # print(f"\nDatasets list retrieved with {len(datasets_dict.get('datasets', []))} datasets")
342
+ #
343
+ # if not datasets_dict.get("datasets"):
344
+ # # If no datasets with specified status, try without status filter
345
+ # if status:
346
+ # print(f"\nNo datasets with status '{status}', fetching any dataset")
347
+ # datasets = dataset_client.list_datasets()
348
+ # datasets_dict = datasets.to_dict()
349
+ #
350
+ # if not datasets_dict.get("datasets"):
351
+ # return None
352
+ #
353
+ # dataset_name = datasets_dict["datasets"][0]
354
+ # print(f"\nSelected dataset: {dataset_name}")
355
+ # return dataset_name
356
356
 
357
357
 
358
358
  # ----------------------------
@@ -475,13 +475,13 @@ def test_batch_detect(guardrails_client, sample_detectors):
475
475
  def test_scan_url(guardrails_client):
476
476
  print("\n\nTesting scan url method")
477
477
  # Test the scan url method
478
- response = guardrails_client.scan_url(url="https://www.digitalocean.com/community/tutorials/how-to-install-poetry-to-manage-python-dependencies-on-ubuntu-22-04")
478
+ response = guardrails_client.scan_url(url="https://example.com/?q=<script>alert('XSS')</script>")
479
479
  print("\nResponse from scan url: ", response)
480
480
  print("\nResponse data type: ", type(response))
481
481
  assert response is not None
482
- assert response.url == "https://www.digitalocean.com/community/tutorials/how-to-install-poetry-to-manage-python-dependencies-on-ubuntu-22-04"
483
- assert response.violations is not None
484
- assert len(response.violations) > 0
482
+ assert response.url == "https://example.com/?q=<script>alert('XSS')</script>"
483
+ # assert response.violations is not None
484
+ # assert len(response.violations) > 0
485
485
 
486
486
 
487
487
  def test_pii_request(guardrails_client):
@@ -642,13 +642,47 @@ def test_batch_detect_with_policy(guardrails_client):
642
642
  def test_scan_url_with_policy(guardrails_client):
643
643
  print("\n\nTesting scan url method with policy")
644
644
  # Test the scan url method
645
- response = guardrails_client.policy_scan_url(policy_name=test_guardrails_policy_name, url="https://www.digitalocean.com/community/tutorials/how-to-install-poetry-to-manage-python-dependencies-on-ubuntu-22-04")
645
+ response = guardrails_client.policy_scan_url(policy_name=test_guardrails_policy_name, url="https://example.com/?q=<script>alert('XSS')</script>")
646
646
  print("\nResponse from scan url: ", response)
647
647
  print("\nResponse data type: ", type(response))
648
648
  assert response is not None
649
- assert response.url == "https://www.digitalocean.com/community/tutorials/how-to-install-poetry-to-manage-python-dependencies-on-ubuntu-22-04"
650
- assert response.violations is not None
651
- assert len(response.violations) > 0
649
+ assert response.url == "https://example.com/?q=<script>alert('XSS')</script>"
650
+ # assert response.violations is not None
651
+ # assert len(response.violations) > 0
652
+
653
+
654
+ def test_scan_pdf(guardrails_client):
655
+ print("\n\nTesting scan pdf method")
656
+ import base64
657
+ # Create a minimal valid PDF for testing
658
+ pdf_path = "../docs/healthcare_guidelines.pdf"
659
+ with open(pdf_path, "rb") as f:
660
+ pdf_base64 = base64.b64encode(f.read()).decode("utf-8")
661
+ response = guardrails_client.scan_pdf(file=pdf_base64)
662
+ print("\nResponse from scan pdf: ", response)
663
+ print("\nResponse data type: ", type(response))
664
+ assert response is not None
665
+ assert hasattr(response, "summary")
666
+ assert hasattr(response, "details")
667
+ assert response.details.total_pages >= 1
668
+
669
+
670
+ def test_scan_pdf_with_policy(guardrails_client):
671
+ print("\n\nTesting scan pdf method with policy")
672
+ import base64
673
+ pdf_path = "../docs/healthcare_guidelines.pdf"
674
+ with open(pdf_path, "rb") as f:
675
+ pdf_base64 = base64.b64encode(f.read()).decode("utf-8")
676
+ response = guardrails_client.policy_scan_pdf(
677
+ policy_name=test_guardrails_policy_name,
678
+ file=pdf_base64
679
+ )
680
+ print("\nResponse from scan pdf with policy: ", response)
681
+ print("\nResponse data type: ", type(response))
682
+ assert response is not None
683
+ assert hasattr(response, "summary")
684
+ assert hasattr(response, "details")
685
+ assert response.details.total_pages >= 1
652
686
 
653
687
 
654
688
  def test_atomize_policy(guardrails_client):
@@ -982,113 +1016,113 @@ def test_401_err_chat(ai_proxy_err_client, sample_chat_body):
982
1016
  # Tests for Dataset Endpoints
983
1017
  # ----------------------------
984
1018
 
985
- def test_add_dataset(dataset_client, sample_dataset_config):
986
- print("\n\nTesting add_dataset")
987
- response = dataset_client.add_dataset(config=sample_dataset_config)
988
- print("\nAdd Dataset Response: ", response)
989
- assert response is not None
990
- assert hasattr(response, "task_id")
991
- assert hasattr(response, "message")
992
- response.message == "Dataset task has been added successfully"
993
- # Sleep for a while to let the task complete
994
- # This is also useful to avoid rate limiting issues
995
- print("\nSleeping for 60 seconds to let the task complete if possible ...")
996
- time.sleep(60)
1019
+ # def test_add_dataset(dataset_client, sample_dataset_config):
1020
+ # print("\n\nTesting add_dataset")
1021
+ # response = dataset_client.add_dataset(config=sample_dataset_config)
1022
+ # print("\nAdd Dataset Response: ", response)
1023
+ # assert response is not None
1024
+ # assert hasattr(response, "task_id")
1025
+ # assert hasattr(response, "message")
1026
+ # response.message == "Dataset task has been added successfully"
1027
+ # # Sleep for a while to let the task complete
1028
+ # # This is also useful to avoid rate limiting issues
1029
+ # print("\nSleeping for 60 seconds to let the task complete if possible ...")
1030
+ # time.sleep(60)
997
1031
 
998
1032
 
999
- def test_list_datasets(dataset_client):
1000
- print("\n\nTesting list_datasets")
1001
- # Test the list_datasets method
1002
- datasets = dataset_client.list_datasets(status="Finished")
1003
- datasets_dict = datasets.to_dict()
1004
- print("\nList Datasets Response: ", datasets_dict)
1005
- assert datasets_dict is not None
1006
- assert isinstance(datasets_dict, dict)
1007
-
1008
- # Get a dataset name using our helper function
1009
- global picked_dataset_name
1010
- if picked_dataset_name is None:
1011
- picked_dataset_name = get_dataset_name_from_list(dataset_client, status="Finished")
1012
- assert picked_dataset_name is not None
1013
- print(f"\nSelected dataset for further tests: {picked_dataset_name}")
1014
-
1015
-
1016
- def test_get_dataset_task(dataset_client):
1017
- print("\n\nTesting get_dataset_task")
1018
- global picked_dataset_name
1019
- if picked_dataset_name is None:
1020
- picked_dataset_name = get_dataset_name_from_list(dataset_client, status="Finished")
1021
- assert picked_dataset_name is not None
1022
- print(f"\nSelected dataset for further tests: {picked_dataset_name}")
1023
-
1024
- # Now test the get_dataset_task method
1025
- dataset_task = dataset_client.get_dataset_task(dataset_name=picked_dataset_name)
1026
- print("\nDataset Task: ", dataset_task)
1027
- assert dataset_task is not None
1028
- assert hasattr(dataset_task, "dataset_name")
1029
- assert dataset_task.dataset_name == picked_dataset_name
1030
- assert hasattr(dataset_task, "data")
1031
- data = dataset_task.data
1032
- assert data is not None
1033
- assert hasattr(data, "status")
1034
- status = data.status
1035
- assert status is not None
1036
- print("\nDataset Task Status: ", status)
1037
-
1038
-
1039
- def test_get_dataset_task_status(dataset_client):
1040
- print("\n\nTesting get_dataset_task_status")
1041
- global picked_dataset_name
1042
- if picked_dataset_name is None:
1043
- picked_dataset_name = get_dataset_name_from_list(dataset_client, status="Finished")
1044
- assert picked_dataset_name is not None
1045
- print(f"\nSelected dataset for further tests: {picked_dataset_name}")
1046
-
1047
- # Now test the get_dataset_task_status method
1048
- dataset_task_status = dataset_client.get_dataset_task_status(dataset_name=picked_dataset_name)
1049
- print("\nDataset Task Status: ", dataset_task_status)
1050
- assert dataset_task_status is not None
1051
- assert hasattr(dataset_task_status, "dataset_name")
1052
- assert dataset_task_status.dataset_name == picked_dataset_name
1053
- assert hasattr(dataset_task_status, "status")
1054
-
1055
-
1056
- def test_get_datacard(dataset_client):
1057
- print("\n\nTesting get_datacard")
1058
- global picked_dataset_name
1059
- if picked_dataset_name is None:
1060
- picked_dataset_name = get_dataset_name_from_list(dataset_client, status="Finished")
1061
- assert picked_dataset_name is not None
1062
- print(f"\nSelected dataset for further tests: {picked_dataset_name}")
1063
-
1064
- # Now test the get_datacard method
1065
- datacard = dataset_client.get_datacard(dataset_name=picked_dataset_name)
1066
- print("\nDatacard: ", datacard)
1067
- assert datacard is not None
1068
- # # Dataset might not be generated yet
1069
- # # TODO: How to handle this?
1070
- # assert hasattr(datacard, "dataset_name")
1071
- # assert datacard.dataset_name == picked_dataset_name
1072
- # assert hasattr(datacard, "description")
1073
-
1074
-
1075
- def test_get_summary(dataset_client):
1076
- print("\n\nTesting get_summary")
1077
- global picked_dataset_name
1078
- if picked_dataset_name is None:
1079
- picked_dataset_name = get_dataset_name_from_list(dataset_client, status="Finished")
1080
- assert picked_dataset_name is not None
1081
- print(f"\nSelected dataset for further tests: {picked_dataset_name}")
1082
-
1083
- # Now test the get_summary method
1084
- summary = dataset_client.get_summary(dataset_name=picked_dataset_name)
1085
- print("\nsummary: ", summary)
1086
- assert summary is not None
1087
- # # Dataset might not be generated yet
1088
- # # TODO: How to handle this?
1089
- # assert hasattr(summary, "dataset_name")
1090
- # assert summary.dataset_name == picked_dataset_name
1091
- # assert hasattr(summary, "test_types")
1033
+ # def test_list_datasets(dataset_client):
1034
+ # print("\n\nTesting list_datasets")
1035
+ # # Test the list_datasets method
1036
+ # datasets = dataset_client.list_datasets(status="Finished")
1037
+ # datasets_dict = datasets.to_dict()
1038
+ # print("\nList Datasets Response: ", datasets_dict)
1039
+ # assert datasets_dict is not None
1040
+ # assert isinstance(datasets_dict, dict)
1041
+ #
1042
+ # # Get a dataset name using our helper function
1043
+ # global picked_dataset_name
1044
+ # if picked_dataset_name is None:
1045
+ # picked_dataset_name = get_dataset_name_from_list(dataset_client, status="Finished")
1046
+ # assert picked_dataset_name is not None
1047
+ # print(f"\nSelected dataset for further tests: {picked_dataset_name}")
1048
+
1049
+
1050
+ # def test_get_dataset_task(dataset_client):
1051
+ # print("\n\nTesting get_dataset_task")
1052
+ # global picked_dataset_name
1053
+ # if picked_dataset_name is None:
1054
+ # picked_dataset_name = get_dataset_name_from_list(dataset_client, status="Finished")
1055
+ # assert picked_dataset_name is not None
1056
+ # print(f"\nSelected dataset for further tests: {picked_dataset_name}")
1057
+ #
1058
+ # # Now test the get_dataset_task method
1059
+ # dataset_task = dataset_client.get_dataset_task(dataset_name=picked_dataset_name)
1060
+ # print("\nDataset Task: ", dataset_task)
1061
+ # assert dataset_task is not None
1062
+ # assert hasattr(dataset_task, "dataset_name")
1063
+ # assert dataset_task.dataset_name == picked_dataset_name
1064
+ # assert hasattr(dataset_task, "data")
1065
+ # data = dataset_task.data
1066
+ # assert data is not None
1067
+ # assert hasattr(data, "status")
1068
+ # status = data.status
1069
+ # assert status is not None
1070
+ # print("\nDataset Task Status: ", status)
1071
+
1072
+
1073
+ # def test_get_dataset_task_status(dataset_client):
1074
+ # print("\n\nTesting get_dataset_task_status")
1075
+ # global picked_dataset_name
1076
+ # if picked_dataset_name is None:
1077
+ # picked_dataset_name = get_dataset_name_from_list(dataset_client, status="Finished")
1078
+ # assert picked_dataset_name is not None
1079
+ # print(f"\nSelected dataset for further tests: {picked_dataset_name}")
1080
+ #
1081
+ # # Now test the get_dataset_task_status method
1082
+ # dataset_task_status = dataset_client.get_dataset_task_status(dataset_name=picked_dataset_name)
1083
+ # print("\nDataset Task Status: ", dataset_task_status)
1084
+ # assert dataset_task_status is not None
1085
+ # assert hasattr(dataset_task_status, "dataset_name")
1086
+ # assert dataset_task_status.dataset_name == picked_dataset_name
1087
+ # assert hasattr(dataset_task_status, "status")
1088
+
1089
+
1090
+ # def test_get_datacard(dataset_client):
1091
+ # print("\n\nTesting get_datacard")
1092
+ # global picked_dataset_name
1093
+ # if picked_dataset_name is None:
1094
+ # picked_dataset_name = get_dataset_name_from_list(dataset_client, status="Finished")
1095
+ # assert picked_dataset_name is not None
1096
+ # print(f"\nSelected dataset for further tests: {picked_dataset_name}")
1097
+ #
1098
+ # # Now test the get_datacard method
1099
+ # datacard = dataset_client.get_datacard(dataset_name=picked_dataset_name)
1100
+ # print("\nDatacard: ", datacard)
1101
+ # assert datacard is not None
1102
+ # # # Dataset might not be generated yet
1103
+ # # # TODO: How to handle this?
1104
+ # # assert hasattr(datacard, "dataset_name")
1105
+ # # assert datacard.dataset_name == picked_dataset_name
1106
+ # # assert hasattr(datacard, "description")
1107
+
1108
+
1109
+ # def test_get_summary(dataset_client):
1110
+ # print("\n\nTesting get_summary")
1111
+ # global picked_dataset_name
1112
+ # if picked_dataset_name is None:
1113
+ # picked_dataset_name = get_dataset_name_from_list(dataset_client, status="Finished")
1114
+ # assert picked_dataset_name is not None
1115
+ # print(f"\nSelected dataset for further tests: {picked_dataset_name}")
1116
+ #
1117
+ # # Now test the get_summary method
1118
+ # summary = dataset_client.get_summary(dataset_name=picked_dataset_name)
1119
+ # print("\nsummary: ", summary)
1120
+ # assert summary is not None
1121
+ # # # Dataset might not be generated yet
1122
+ # # # TODO: How to handle this?
1123
+ # # assert hasattr(summary, "dataset_name")
1124
+ # # assert summary.dataset_name == picked_dataset_name
1125
+ # # assert hasattr(summary, "test_types")
1092
1126
 
1093
1127
 
1094
1128
  # ----------------------------
File without changes
File without changes
File without changes