openguardrails 3.0.0__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.
@@ -0,0 +1,188 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity granting the License.
13
+
14
+ "Legal Entity" shall mean the union of the acting entity and all
15
+ other entities that control, are controlled by, or are under common
16
+ control with that entity. For the purposes of this definition,
17
+ "control" means (i) the power, direct or indirect, to cause the
18
+ direction or management of such entity, whether by contract or
19
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
20
+ outstanding shares, or (iii) beneficial ownership of such entity.
21
+
22
+ "You" (or "Your") shall mean an individual or Legal Entity
23
+ exercising permissions granted by this License.
24
+
25
+ "Source" shall mean the preferred form for making modifications,
26
+ including but not limited to software source code, documentation
27
+ source, and configuration files.
28
+
29
+ "Object" shall mean any form resulting from mechanical
30
+ transformation or translation of a Source form, including but
31
+ not limited to compiled object code, generated documentation,
32
+ and conversions to other media types.
33
+
34
+ "Work" shall mean the work of authorship, whether in Source or
35
+ Object form, made available under the License, as indicated by a
36
+ copyright notice that is included in or attached to the work
37
+ (which shall not include communications that are posted in
38
+ conspicuous places as prominently to announce that the work is
39
+ published under this particular License).
40
+
41
+ "Derivative Works" shall mean any work, whether in Source or Object
42
+ form, that is based upon (or derived from) the Work and for which the
43
+ editorial revisions, annotations, elaborations, or other modifications
44
+ represent, as a whole, an original work of authorship. For the purposes
45
+ of this License, Derivative Works shall not include works that remain
46
+ separable from, or merely link (or bind by name) to the interfaces of,
47
+ the Work and derivative works thereof.
48
+
49
+ "Contribution" shall mean any work of authorship, including
50
+ the original version of the Work and any modifications or additions
51
+ to that Work or Derivative Works thereof, that is intentionally
52
+ submitted to Licensor for inclusion in the Work by the copyright owner
53
+ or by an individual or Legal Entity authorized to submit on behalf of
54
+ the copyright owner. For the purposes of this definition, "submitted"
55
+ means any form of electronic, verbal, or written communication sent
56
+ to the Licensor or its representatives, including but not limited to
57
+ communication on electronic mailing lists, source code control
58
+ systems, and issue tracking systems that are managed by, or on behalf
59
+ of, the Licensor for the purpose of discussing and improving the Work,
60
+ but excluding communication that is conspicuously marked or otherwise
61
+ designated in writing by the copyright owner as "Not a Contribution."
62
+
63
+ "Contributor" shall mean Licensor and any individual or Legal Entity
64
+ on behalf of whom a Contribution has been received by Licensor and
65
+ subsequently incorporated within the Work.
66
+
67
+ 2. Grant of Copyright License. Subject to the terms and conditions of
68
+ this License, each Contributor hereby grants to You a perpetual,
69
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70
+ copyright license to use, reproduce, modify, merge, publish,
71
+ distribute, sublicense, and/or sell copies of the Work, and to
72
+ permit persons to whom the Work is furnished to do so, subject to
73
+ the following conditions:
74
+
75
+ The above copyright notice and this permission notice shall be
76
+ included in all copies or substantial portions of the Work.
77
+
78
+ 3. Grant of Patent License. Subject to the terms and conditions of
79
+ this License, each Contributor hereby grants to You a perpetual,
80
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
81
+ (except as stated in this section) patent license to make, have made,
82
+ use, offer to sell, sell, import, and otherwise transfer the Work,
83
+ where such license applies only to those patent claims licensable
84
+ by such Contributor that are necessarily infringed by their
85
+ Contribution(s) alone or by combination of their Contribution(s)
86
+ with the Work to which such Contribution(s) was submitted. If You
87
+ institute patent litigation against any entity (including a
88
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
89
+ or a Contribution incorporated within the Work constitutes direct
90
+ or contributory patent infringement, then any patent licenses
91
+ granted to You under this License for that Work shall terminate
92
+ as of the date such litigation is filed.
93
+
94
+ 4. Redistribution. You may reproduce and distribute copies of the
95
+ Work or Derivative Works thereof in any medium, with or without
96
+ modifications, and in Source or Object form, provided that You
97
+ meet the following conditions:
98
+
99
+ (a) You must give any other recipients of the Work or
100
+ Derivative Works a copy of this License; and
101
+
102
+ (b) You must cause any modified files to carry prominent notices
103
+ stating that You changed the files; and
104
+
105
+ (c) You must retain, in the Source form of any Derivative Works
106
+ that You distribute, all copyright, trademark, patent,
107
+ and attribution notices from the Source form of the Work,
108
+ excluding those notices that do not pertain to any part of
109
+ the Derivative Works; and
110
+
111
+ (d) If the Work includes a "NOTICE" text file as part of its
112
+ distribution, then any Derivative Works that You distribute must
113
+ include a readable copy of the attribution notices contained
114
+ within such NOTICE file, excluding those notices that do not
115
+ pertain to any part of the Derivative Works, in at least one
116
+ of the following places: within a NOTICE text file distributed
117
+ as part of the Derivative Works; within the Source form or
118
+ documentation, if provided along with the Derivative Works; or,
119
+ within a display generated by the Derivative Works, if and
120
+ wherever such third-party notices normally appear. The contents
121
+ of the NOTICE file are for informational purposes only and
122
+ do not modify the License. You may add Your own attribution
123
+ notices within Derivative Works that You distribute, alongside
124
+ or as an addendum to the NOTICE text from the Work, provided
125
+ that such additional attribution notices cannot be construed
126
+ as modifying the License.
127
+
128
+ You may add Your own copyright notice to Your modifications and
129
+ may provide additional or different license terms and conditions
130
+ for use, reproduction, or distribution of Your modifications, or
131
+ for any such Derivative Works as a whole, provided Your use,
132
+ reproduction, and distribution of the Work otherwise complies with
133
+ the conditions stated in this License.
134
+
135
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
136
+ any Contribution intentionally submitted for inclusion in the Work
137
+ by You to the Licensor shall be under the terms and conditions of
138
+ this License, without any additional terms or conditions.
139
+ Notwithstanding the above, nothing herein shall supersede or modify
140
+ the terms of any separate license agreement you may have executed
141
+ with Licensor regarding such Contributions.
142
+
143
+ 6. Trademarks. This License does not grant permission to use the trade
144
+ names, trademarks, service marks, or product names of the Licensor,
145
+ except as required for reasonable and customary use in describing the
146
+ origin of the Work and reproducing the content of the NOTICE file.
147
+
148
+ 7. Disclaimer of Warranty. Unless required by applicable law or
149
+ agreed to in writing, Licensor provides the Work (and each
150
+ Contributor provides its Contributions) on an "AS IS" BASIS,
151
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
152
+ implied, including, without limitation, any warranties or conditions
153
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
154
+ PARTICULAR PURPOSE. You are solely responsible for determining the
155
+ appropriateness of using or redistributing the Work and assume any
156
+ risks associated with Your exercise of permissions under this License.
157
+
158
+ 8. Limitation of Liability. In no event and under no legal theory,
159
+ whether in tort (including negligence), contract, or otherwise,
160
+ unless required by applicable law (such as deliberate and grossly
161
+ negligent acts) or agreed to in writing, shall any Contributor be
162
+ liable to You for damages, including any direct, indirect, special,
163
+ incidental, or consequential damages of any character arising as a
164
+ result of this License or out of the use or inability to use the
165
+ Work (including but not limited to damages for loss of goodwill,
166
+ work stoppage, computer failure or malfunction, or any and all
167
+ other commercial damages or losses), even if such Contributor
168
+ has been advised of the possibility of such damages.
169
+
170
+ 9. Accepting Warranty or Support. Unless required by applicable law or
171
+ agreed to in writing, You may not accept any warranty or support
172
+ from Licensor for the Work except as may be provided in this License.
173
+
174
+ END OF TERMS AND CONDITIONS
175
+
176
+ Copyright 2025 OpenGuardrails
177
+
178
+ Licensed under the Apache License, Version 2.0 (the "License");
179
+ you may not use this file except in compliance with the License.
180
+ You may obtain a copy of the License at
181
+
182
+ http://www.apache.org/licenses/LICENSE-2.0
183
+
184
+ Unless required by applicable law or agreed to in writing, software
185
+ distributed under the License is distributed on an "AS IS" BASIS,
186
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
187
+ See the License for the specific language governing permissions and
188
+ limitations under the License.
@@ -0,0 +1,8 @@
1
+ include README.md
2
+ include LICENSE
3
+ include pyproject.toml
4
+ recursive-include src/openguardrails *.py
5
+ recursive-include src/openguardrails py.typed
6
+ recursive-exclude * __pycache__
7
+ recursive-exclude * *.py[co]
8
+ recursive-exclude tests *
@@ -0,0 +1,424 @@
1
+ Metadata-Version: 2.4
2
+ Name: openguardrails
3
+ Version: 3.0.0
4
+ Summary: OpenGuardrails Python SDK - An LLM-based context-aware AI guardrail that understands conversation context for security, safety and data leakage detection.
5
+ Author-email: OpenGuardrails <thomas@openguardrails.com>
6
+ Maintainer-email: OpenGuardrails <thomas@openguardrails.com>
7
+ License-Expression: Apache-2.0
8
+ Project-URL: Homepage, https://openguardrails.com
9
+ Project-URL: Documentation, https://openguardrails.com
10
+ Project-URL: Repository, https://github.com/openguardrails/openguardrails
11
+ Project-URL: Issues, https://github.com/openguardrails/openguardrails/issues
12
+ Project-URL: Changelog, https://github.com/openguardrails/openguardrails/blob/main/CHANGELOG.md
13
+ Keywords: ai,safety,guardrails,llm,content-moderation,prompt-injection,security,compliance,openguardrails
14
+ Classifier: Development Status :: 4 - Beta
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.8
19
+ Classifier: Programming Language :: Python :: 3.9
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
24
+ Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers
25
+ Classifier: Topic :: Security
26
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
27
+ Requires-Python: >=3.8
28
+ Description-Content-Type: text/markdown
29
+ License-File: LICENSE
30
+ Requires-Dist: requests>=2.25.0
31
+ Requires-Dist: aiohttp>=3.8.0
32
+ Requires-Dist: typing-extensions>=4.0.0
33
+ Requires-Dist: pydantic>=2.0.0
34
+ Provides-Extra: dev
35
+ Requires-Dist: pytest>=6.0.0; extra == "dev"
36
+ Requires-Dist: pytest-cov>=3.0.0; extra == "dev"
37
+ Requires-Dist: black>=22.0.0; extra == "dev"
38
+ Requires-Dist: isort>=5.0.0; extra == "dev"
39
+ Requires-Dist: flake8>=4.0.0; extra == "dev"
40
+ Requires-Dist: mypy>=1.0.0; extra == "dev"
41
+ Requires-Dist: types-requests; extra == "dev"
42
+ Provides-Extra: test
43
+ Requires-Dist: pytest>=6.0.0; extra == "test"
44
+ Requires-Dist: pytest-cov>=3.0.0; extra == "test"
45
+ Requires-Dist: responses>=0.18.0; extra == "test"
46
+ Dynamic: license-file
47
+
48
+ # OpenGuardrails Python Client
49
+
50
+ [![PyPI version](https://badge.fury.io/py/openguardrails.svg)](https://badge.fury.io/py/openguardrails)
51
+ [![Python Support](https://img.shields.io/pypi/pyversions/openguardrails.svg)](https://pypi.org/project/openguardrails/)
52
+ [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
53
+
54
+ An LLM-based context-aware AI guardrail that understands conversation context for security, safety and data leakage detection.
55
+
56
+ ## Features
57
+
58
+ * 🧠 **Context Awareness** – Based on LLM conversation understanding rather than simple batch detection
59
+ * 🔍 **Prompt Injection Detection** – Detects malicious prompt injections and jailbreak attacks
60
+ * 📋 **Content Compliance Detection** – Complies with generative AI safety requirements
61
+ * 🔐 **Sensitive Data Leak Prevention** – Detects and prevents personal or corporate data leaks
62
+ * 🧩 **User-level Ban Policy** – Supports user-granular risk recognition and blocking strategies
63
+ * 🖼️ **Multimodal Detection** – Supports image content safety detection
64
+ * 🛠️ **Easy Integration** – OpenAI-compatible API format; plug in with one line of code
65
+ * ⚡ **OpenAI-style API** – Familiar interface design for rapid adoption
66
+ * 🚀 **Sync/Async Support** – Supports both synchronous and asynchronous calls for different scenarios
67
+
68
+ ## Installation
69
+
70
+ ```bash
71
+ pip install openguardrails
72
+ ```
73
+
74
+ ## Quick Start
75
+
76
+ ### Basic Usage
77
+
78
+ ```python
79
+ from openguardrails import OpenGuardrails
80
+
81
+ # Create a client
82
+ client = OpenGuardrails(
83
+ api_key="your-api-key",
84
+ base_url="https://api.openguardrails.com/v1" # Cloud API
85
+ )
86
+
87
+ # Check user input
88
+ result = client.check_prompt("I want to learn Python programming", user_id="user-123")
89
+ print(result.suggest_action) # Output: pass
90
+ print(result.overall_risk_level) # Output: no_risk
91
+ print(result.score) # Confidence score, e.g. 0.9993114447238793
92
+
93
+ # Check model response (context-aware)
94
+ result = client.check_response_ctx(
95
+ prompt="Teach me how to cook",
96
+ response="I can teach you some simple home dishes",
97
+ user_id="user-123" # Optional user-level risk control
98
+ )
99
+ print(result.suggest_action) # Output: pass
100
+ print(result.overall_risk_level) # Output: no_risk
101
+ ```
102
+
103
+ ### Context-Aware Detection (Core Feature)
104
+
105
+ ```python
106
+ # Context-based conversation detection - Core feature
107
+ messages = [
108
+ {"role": "user", "content": "I want to learn chemistry"},
109
+ {"role": "assistant", "content": "Chemistry is an interesting subject. What part would you like to learn?"},
110
+ {"role": "user", "content": "Teach me reactions for making explosives"}
111
+ ]
112
+
113
+ result = client.check_conversation(messages, user_id="user-123")
114
+ print(result.overall_risk_level)
115
+ print(result.suggest_action) # Result based on full conversation context
116
+ if result.suggest_answer:
117
+ print(f"Suggested answer: {result.suggest_answer}")
118
+ ```
119
+
120
+ ### Asynchronous API (Recommended)
121
+
122
+ ```python
123
+ import asyncio
124
+ from openguardrails import AsyncOpenGuardrails
125
+
126
+ async def main():
127
+ async with AsyncOpenGuardrails(api_key="your-api-key") as client:
128
+ # Async prompt check
129
+ result = await client.check_prompt("I want to learn Python programming")
130
+ print(result.suggest_action) # Output: pass
131
+
132
+ # Async conversation context check
133
+ messages = [
134
+ {"role": "user", "content": "I want to learn chemistry"},
135
+ {"role": "assistant", "content": "Chemistry is an interesting subject. What part would you like to learn?"},
136
+ {"role": "user", "content": "Teach me reactions for making explosives"}
137
+ ]
138
+ result = await client.check_conversation(messages)
139
+ print(result.overall_risk_level)
140
+
141
+ asyncio.run(main())
142
+ ```
143
+
144
+ ### Concurrent Processing
145
+
146
+ ```python
147
+ import asyncio
148
+ from openguardrails import AsyncOpenGuardrails
149
+
150
+ async def batch_check():
151
+ async with AsyncOpenGuardrails(api_key="your-api-key") as client:
152
+ # Handle multiple requests concurrently
153
+ tasks = [
154
+ client.check_prompt("Content 1"),
155
+ client.check_prompt("Content 2"),
156
+ client.check_prompt("Content 3")
157
+ ]
158
+ results = await asyncio.gather(*tasks)
159
+
160
+ for i, result in enumerate(results):
161
+ print(f"Content {i+1}: {result.overall_risk_level}")
162
+
163
+ asyncio.run(batch_check())
164
+ ```
165
+
166
+ ### Multimodal Image Detection
167
+
168
+ Supports multimodal detection for image content safety. The system analyzes both text prompt semantics and image semantics for risk.
169
+
170
+ ```python
171
+ from openguardrails import OpenGuardrails
172
+
173
+ client = OpenGuardrails(api_key="your-api-key")
174
+
175
+ # Check a single local image
176
+ result = client.check_prompt_image(
177
+ prompt="Is this image safe?",
178
+ image="/path/to/image.jpg"
179
+ )
180
+ print(result.overall_risk_level)
181
+ print(result.suggest_action)
182
+
183
+ # Check an image from URL
184
+ result = client.check_prompt_image(
185
+ prompt="", # prompt can be empty
186
+ image="https://example.com/image.jpg"
187
+ )
188
+
189
+ # Check multiple images
190
+ images = [
191
+ "/path/to/image1.jpg",
192
+ "https://example.com/image2.jpg",
193
+ "/path/to/image3.png"
194
+ ]
195
+ result = client.check_prompt_images(
196
+ prompt="Are all these images safe?",
197
+ images=images
198
+ )
199
+ print(result.overall_risk_level)
200
+ ```
201
+
202
+ Async version:
203
+
204
+ ```python
205
+ import asyncio
206
+ from openguardrails import AsyncOpenGuardrails
207
+
208
+ async def check_images():
209
+ async with AsyncOpenGuardrails(api_key="your-api-key") as client:
210
+ # Async check for a single image
211
+ result = await client.check_prompt_image(
212
+ prompt="Is this image safe?",
213
+ image="/path/to/image.jpg"
214
+ )
215
+ print(result.overall_risk_level)
216
+
217
+ # Async check for multiple images
218
+ images = ["/path/to/image1.jpg", "/path/to/image2.jpg"]
219
+ result = await client.check_prompt_images(
220
+ prompt="Are these images safe?",
221
+ images=images
222
+ )
223
+ print(result.overall_risk_level)
224
+
225
+ asyncio.run(check_images())
226
+ ```
227
+
228
+ ### On-Premise Deployment
229
+
230
+ ```python
231
+ # Sync client connecting to local deployment
232
+ client = OpenGuardrails(
233
+ api_key="your-local-api-key",
234
+ base_url="http://localhost:5000/v1"
235
+ )
236
+
237
+ # Async client connecting to local deployment
238
+ async with AsyncOpenGuardrails(
239
+ api_key="your-local-api-key",
240
+ base_url="http://localhost:5000/v1"
241
+ ) as client:
242
+ result = await client.check_prompt("Test content")
243
+ ```
244
+
245
+ ## API Reference
246
+
247
+ ### OpenGuardrails Class (Synchronous)
248
+
249
+ #### Initialization Parameters
250
+
251
+ * `api_key` (str): API key
252
+ * `base_url` (str): Base API URL, defaults to the cloud endpoint
253
+ * `timeout` (int): Request timeout, default 30 seconds
254
+ * `max_retries` (int): Maximum retry count, default 3
255
+
256
+ #### Methods
257
+
258
+ ##### check_prompt(content: str, user_id: Optional[str] = None) -> GuardrailResponse
259
+
260
+ Checks the safety of a single prompt.
261
+
262
+ **Parameters:**
263
+
264
+ * `content`: Text content to be checked
265
+ * `user_id`: Optional tenant user ID for per-user risk control and auditing
266
+
267
+ **Returns:** `GuardrailResponse` object
268
+
269
+ ##### check_conversation(messages: List[Message], model: str = "OpenGuardrails-Text", user_id: Optional[str] = None) -> GuardrailResponse
270
+
271
+ Checks conversation context safety (core feature).
272
+
273
+ **Parameters:**
274
+
275
+ * `messages`: List of messages, each containing `role` and `content`
276
+ * `model`: Model name (default: "OpenGuardrails-Text")
277
+ * `user_id`: Optional tenant user ID
278
+
279
+ **Returns:** `GuardrailResponse` object
280
+
281
+ ### AsyncOpenGuardrails Class (Asynchronous)
282
+
283
+ Same initialization parameters as the synchronous version.
284
+
285
+ #### Methods
286
+
287
+ ##### async check_prompt(content: str) -> GuardrailResponse
288
+
289
+ Asynchronously checks a single prompt.
290
+
291
+ ##### async check_conversation(messages: List[Message]) -> GuardrailResponse
292
+
293
+ Asynchronously checks conversation context safety (core feature).
294
+
295
+ ##### async health_check() -> Dict[str, Any]
296
+
297
+ Checks API service health.
298
+
299
+ ##### async get_models() -> Dict[str, Any]
300
+
301
+ Retrieves available model list.
302
+
303
+ ##### async close()
304
+
305
+ Closes async session (automatically handled with `async with`).
306
+
307
+ ### GuardrailResponse Class
308
+
309
+ Represents detection results.
310
+
311
+ #### Attributes
312
+
313
+ * `id`: Unique request ID
314
+ * `result.compliance.risk_level`: Compliance risk level
315
+ * `result.security.risk_level`: Security risk level
316
+ * `result.data.risk_level`: Data leak risk level (added in v2.4.0)
317
+ * `result.data.categories`: Detected sensitive data types (added in v2.4.0)
318
+ * `overall_risk_level`: Overall risk level (none / low / medium / high)
319
+ * `suggest_action`: Suggested action (pass / block / substitute)
320
+ * `suggest_answer`: Suggested response (optional, includes redacted content if applicable)
321
+ * `score`: Confidence score of the results
322
+
323
+ #### Helper Methods
324
+
325
+ * `is_safe`: Whether the content is safe
326
+ * `is_blocked`: Whether the content is blocked
327
+ * `has_substitute`: Whether a substitute answer is provided
328
+ * `all_categories`: Get all detected risk categories
329
+
330
+ ## Safety Detection Capabilities
331
+
332
+ ### Risk Levels
333
+
334
+ * **High Risk:** Sensitive political topics, national image damage, violent crime, prompt attacks
335
+ * **Medium Risk:** General political topics, harm to minors, illegal acts, sexual content
336
+ * **Low Risk:** Hate speech, insults, privacy violations, commercial misconduct
337
+ * **No Risk:** Safe content
338
+
339
+ ### Handling Strategies
340
+
341
+ * **High Risk:** Recommend blocking
342
+ * **Medium Risk:** Recommend substitution with a safe reply
343
+ * **Low Risk:** Recommend substitution or business-dependent handling
344
+ * **No Risk:** Recommend pass
345
+
346
+ ## Error Handling
347
+
348
+ ### Synchronous Error Handling
349
+
350
+ ```python
351
+ from openguardrails import OpenGuardrails, AuthenticationError, ValidationError, RateLimitError
352
+
353
+ try:
354
+ result = client.check_prompt("Test content")
355
+ except AuthenticationError:
356
+ print("Invalid API key")
357
+ except ValidationError as e:
358
+ print(f"Input validation failed: {e}")
359
+ except RateLimitError:
360
+ print("Rate limit exceeded")
361
+ except Exception as e:
362
+ print(f"Other error: {e}")
363
+ ```
364
+
365
+ ### Asynchronous Error Handling
366
+
367
+ ```python
368
+ import asyncio
369
+ from openguardrails import AsyncOpenGuardrails, AuthenticationError, ValidationError, RateLimitError
370
+
371
+ async def safe_check():
372
+ try:
373
+ async with AsyncOpenGuardrails(api_key="your-api-key") as client:
374
+ result = await client.check_prompt("Test content")
375
+ return result
376
+ except AuthenticationError:
377
+ print("Invalid API key")
378
+ except ValidationError as e:
379
+ print(f"Input validation failed: {e}")
380
+ except RateLimitError:
381
+ print("Rate limit exceeded")
382
+ except Exception as e:
383
+ print(f"Other error: {e}")
384
+
385
+ asyncio.run(safe_check())
386
+ ```
387
+
388
+ ## Development
389
+
390
+ ```bash
391
+ # Clone the project
392
+ git clone https://github.com/openguardrails/openguardrails
393
+ cd openguardrails/client
394
+
395
+ # Install dev dependencies
396
+ pip install -e ".[dev]"
397
+
398
+ # Run tests
399
+ pytest
400
+
401
+ # Code formatting
402
+ black openguardrails
403
+ isort openguardrails
404
+
405
+ # Type checking
406
+ mypy openguardrails
407
+ ```
408
+
409
+ ## License
410
+
411
+ This project is open-sourced under the [Apache 2.0](https://opensource.org/licenses/Apache-2.0) license.
412
+
413
+ ## Support
414
+
415
+ * 📧 Technical Support: [thomas@openguardrails.com](mailto:thomas@openguardrails.com)
416
+ * 🌐 Official Website: [https://openguardrails.com](https://openguardrails.com)
417
+ * 📖 Documentation: [https://docs.openguardrails.com](https://docs.openguardrails.com)
418
+ * 🐛 Issue Tracker: [https://github.com/openguardrails/openguardrails/issues](https://github.com/openguardrails/openguardrails/issues)
419
+
420
+ ---
421
+
422
+ Made with ❤️ by [Xiangxin AI](https://openguardrails.com)
423
+
424
+ ---