Skip to content

Commit 3e98c70

Browse files
Gabriel Bayomi Tinoco Kalejaiyegustavocidornelas
authored andcommitted
test: add guardrails integration tests and additional examples
- Add comprehensive test suite for guardrails functionality - Include tests for different block strategies and error handling - Add helper functions integration tests - Provide additional usage examples and demonstrations These tests ensure the guardrails system works correctly across all integration points and usage patterns.
1 parent be7d827 commit 3e98c70

File tree

5 files changed

+1238
-0
lines changed

5 files changed

+1238
-0
lines changed
Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
"""
2+
Example: Using Guardrails with Openlayer Tracing
3+
4+
This example demonstrates how to use guardrails to protect against PII leakage
5+
and other security concerns in traced functions.
6+
"""
7+
8+
import os
9+
from openlayer.lib.tracing import tracer
10+
from openlayer.lib.guardrails import PIIGuardrail, GuardrailBlockedException
11+
12+
# Set environment variables (replace with your actual values)
13+
os.environ["OPENLAYER_API_KEY"] = "your_openlayer_api_key_here"
14+
os.environ["OPENLAYER_INFERENCE_PIPELINE_ID"] = "your_pipeline_id_here"
15+
16+
17+
def example_1_no_pii():
18+
"""Example 1: Normal query with no PII - should do nothing."""
19+
print("=== Example 1: No PII Detection ===")
20+
21+
# Create PII guardrail
22+
pii_guardrail = PIIGuardrail(name="PII Protection")
23+
24+
@tracer.trace(guardrails=[pii_guardrail])
25+
def process_query(user_query: str) -> str:
26+
"""Process a user query and return a response."""
27+
return f"Here's information about {user_query}: Turtles are reptiles..."
28+
29+
try:
30+
result = process_query("tell me about turtles")
31+
print(f"Result: {result}")
32+
print("✅ Query processed successfully - no PII detected")
33+
except Exception as e:
34+
print(f"❌ Error: {e}")
35+
36+
37+
def example_2_blocked_ssn():
38+
"""Example 2: Query with SSN - should be blocked."""
39+
print("\n=== Example 2: SSN Detection (Blocked) ===")
40+
41+
# Create PII guardrail with SSN in block list
42+
pii_guardrail = PIIGuardrail(
43+
name="PII Protection",
44+
block_entities={"US_SSN", "CREDIT_CARD"}, # High-risk PII
45+
redact_entities={"PHONE_NUMBER", "EMAIL_ADDRESS"} # Medium-risk PII
46+
)
47+
48+
@tracer.trace(guardrails=[pii_guardrail])
49+
def process_query(user_query: str) -> str:
50+
"""Process a user query and return a response."""
51+
return f"Processing: {user_query}"
52+
53+
try:
54+
result = process_query("here is my SSN: 123-45-6789")
55+
print(f"Result: {result}")
56+
except GuardrailBlockedException as e:
57+
print(f"🚫 Request blocked by guardrail: {e}")
58+
print("✅ Successfully blocked high-risk PII")
59+
except Exception as e:
60+
print(f"❌ Unexpected error: {e}")
61+
62+
63+
def example_3_redacted_phone():
64+
"""Example 3: Query with phone number - should be redacted."""
65+
print("\n=== Example 3: Phone Number Detection (Redacted) ===")
66+
67+
# Create PII guardrail
68+
pii_guardrail = PIIGuardrail(
69+
name="PII Protection",
70+
block_entities={"US_SSN", "CREDIT_CARD"}, # High-risk PII
71+
redact_entities={"PHONE_NUMBER", "EMAIL_ADDRESS", "PERSON"} # Medium-risk PII
72+
)
73+
74+
@tracer.trace(guardrails=[pii_guardrail])
75+
def process_query(user_query: str) -> str:
76+
"""Process a user query and return a response."""
77+
return f"I'll help you with that request: {user_query}"
78+
79+
try:
80+
result = process_query("here is my phone number: 555-123-4567")
81+
print(f"Result: {result}")
82+
print("✅ Phone number successfully redacted")
83+
except Exception as e:
84+
print(f"❌ Error: {e}")
85+
86+
87+
def example_4_multiple_guardrails():
88+
"""Example 4: Multiple guardrails with different configurations."""
89+
print("\n=== Example 4: Multiple Guardrails ===")
90+
91+
# Create multiple guardrails with different settings
92+
strict_pii_guardrail = PIIGuardrail(
93+
name="Strict PII",
94+
block_entities={"US_SSN", "CREDIT_CARD", "US_PASSPORT"},
95+
redact_entities={"PHONE_NUMBER", "EMAIL_ADDRESS"},
96+
confidence_threshold=0.8 # Higher confidence required
97+
)
98+
99+
lenient_pii_guardrail = PIIGuardrail(
100+
name="Lenient PII",
101+
block_entities=set(), # Don't block anything
102+
redact_entities={"PERSON", "LOCATION"},
103+
confidence_threshold=0.6 # Lower confidence threshold
104+
)
105+
106+
@tracer.trace(guardrails=[strict_pii_guardrail, lenient_pii_guardrail])
107+
def process_user_data(user_input: str) -> str:
108+
"""Process user data with multiple guardrail layers."""
109+
return f"Processed data: {user_input}"
110+
111+
try:
112+
result = process_user_data("Hi, I'm John Smith from New York, call me at 555-0123")
113+
print(f"Result: {result}")
114+
print("✅ Multiple guardrails applied successfully")
115+
except GuardrailBlockedException as e:
116+
print(f"🚫 Request blocked: {e}")
117+
except Exception as e:
118+
print(f"❌ Error: {e}")
119+
120+
121+
def example_5_output_guardrails():
122+
"""Example 5: Guardrails on function output."""
123+
print("\n=== Example 5: Output Guardrails ===")
124+
125+
# Create PII guardrail that also checks outputs
126+
pii_guardrail = PIIGuardrail(
127+
name="Input/Output PII Protection",
128+
block_entities={"US_SSN"},
129+
redact_entities={"EMAIL_ADDRESS", "PHONE_NUMBER"}
130+
)
131+
132+
@tracer.trace(guardrails=[pii_guardrail])
133+
def generate_response(query: str) -> str:
134+
"""Generate a response that might contain PII."""
135+
# Simulate a function that might accidentally include PII in output
136+
if "contact" in query.lower():
137+
return "You can reach our support at support@company.com or call 555-HELP"
138+
return "How can I help you today?"
139+
140+
try:
141+
result = generate_response("How do I contact support?")
142+
print(f"Result: {result}")
143+
print("✅ Output PII successfully redacted")
144+
except Exception as e:
145+
print(f"❌ Error: {e}")
146+
147+
148+
def example_6_custom_configuration():
149+
"""Example 6: Custom guardrail configuration."""
150+
print("\n=== Example 6: Custom Configuration ===")
151+
152+
# Create highly customized PII guardrail
153+
custom_pii_guardrail = PIIGuardrail(
154+
name="Custom PII Guardrail",
155+
block_entities={"CREDIT_CARD", "US_SSN", "US_BANK_NUMBER"},
156+
redact_entities={"PHONE_NUMBER", "EMAIL_ADDRESS", "PERSON", "LOCATION", "DATE_TIME"},
157+
confidence_threshold=0.75,
158+
language="en"
159+
)
160+
161+
@tracer.trace(guardrails=[custom_pii_guardrail])
162+
def process_customer_request(request: str) -> str:
163+
"""Process a customer service request."""
164+
return f"Thank you for your request. We'll process: {request}"
165+
166+
try:
167+
result = process_customer_request(
168+
"Hi, I'm Jane Doe from San Francisco. "
169+
"My account issue happened on January 15th, 2024. "
170+
"Please call me at (555) 987-6543 or email jane.doe@email.com"
171+
)
172+
print(f"Result: {result}")
173+
print("✅ Custom guardrail configuration applied")
174+
except GuardrailBlockedException as e:
175+
print(f"🚫 Request blocked: {e}")
176+
except Exception as e:
177+
print(f"❌ Error: {e}")
178+
179+
180+
def example_7_disabled_guardrail():
181+
"""Example 7: Disabled guardrail."""
182+
print("\n=== Example 7: Disabled Guardrail ===")
183+
184+
# Create disabled guardrail
185+
disabled_guardrail = PIIGuardrail(
186+
name="Disabled PII Guardrail",
187+
enabled=False, # Guardrail is disabled
188+
block_entities={"US_SSN"}
189+
)
190+
191+
@tracer.trace(guardrails=[disabled_guardrail])
192+
def process_data(data: str) -> str:
193+
"""Process data with disabled guardrail."""
194+
return f"Processed: {data}"
195+
196+
try:
197+
result = process_data("SSN: 123-45-6789") # Would normally be blocked
198+
print(f"Result: {result}")
199+
print("✅ Disabled guardrail allowed request to pass through")
200+
except Exception as e:
201+
print(f"❌ Error: {e}")
202+
203+
204+
if __name__ == "__main__":
205+
print("Openlayer Guardrails Examples")
206+
print("=" * 50)
207+
208+
# Note: These examples require presidio to be installed
209+
print("Note: These examples require presidio. Install with:")
210+
print("pip install presidio-analyzer presidio-anonymizer")
211+
print()
212+
213+
try:
214+
# Run all examples
215+
example_1_no_pii()
216+
example_2_blocked_ssn()
217+
example_3_redacted_phone()
218+
example_4_multiple_guardrails()
219+
example_5_output_guardrails()
220+
example_6_custom_configuration()
221+
example_7_disabled_guardrail()
222+
223+
print("\n" + "=" * 50)
224+
print("✅ All examples completed!")
225+
print("\nGuardrail metadata is automatically added to your Openlayer traces.")
226+
print("Check your Openlayer dashboard to see the guardrail actions and metadata.")
227+
228+
except ImportError as e:
229+
if "presidio" in str(e):
230+
print(f"❌ Presidio not installed: {e}")
231+
print("Install presidio with: pip install presidio-analyzer presidio-anonymizer")
232+
else:
233+
print(f"❌ Import error: {e}")
234+
except Exception as e:
235+
print(f"❌ Example failed: {e}")
236+
print("\nTo run these examples successfully:")
237+
print("1. Install presidio: pip install presidio-analyzer presidio-anonymizer")
238+
print("2. Replace placeholder API keys with real values")
239+
print("3. Ensure you have a valid Openlayer account and pipeline ID")

0 commit comments

Comments
 (0)