|
| 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