Skip to content

Commit 1238b04

Browse files
committed
Make Presidio a required dependency
1 parent 7bb8bc0 commit 1238b04

File tree

7 files changed

+216
-54
lines changed

7 files changed

+216
-54
lines changed

README.md

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,9 @@ For full details, advanced usage, and API reference, see here: [OpenAI Guardrail
1414
- Use the [Guardrails web UI](https://guardrails.openai.com/) to create a JSON configuration file describing which guardrails to apply and how to configure them.
1515
- The wizard outputs a file like `guardrail_specs.json`.
1616

17-
2. **Install dependencies**
18-
- **Install from this repo:**
17+
2. **Install**
1918
```bash
20-
pip install -e '.[presidio]'
21-
```
22-
- **Eventually this will be:**
23-
```bash
24-
pip install openai-guardrails
19+
pip install guardrails
2520
```
2621

2722
3. **Wrap your OpenAI client with Guardrails**

docs/quickstart.md

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,6 @@ Get started with Guardrails in minutes. Guardrails provides drop-in replacements
88
pip install guardrails
99
```
1010

11-
For PII detection (optional):
12-
```bash
13-
pip install guardrails[presidio]
14-
```
15-
1611
## Set API Key
1712

1813
```bash

examples/basic/hello_world.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,18 @@
1010

1111
console = Console()
1212

13-
# Pipeline configuration with input guardrails
13+
# Pipeline configuration with pre_flight and input guardrails
1414
PIPELINE_CONFIG = {
1515
"version": 1,
16-
"input": {
16+
"pre_flight": {
1717
"version": 1,
1818
"guardrails": [
1919
{"name": "Contains PII", "config": {"entities": ["US_SSN", "PHONE_NUMBER", "EMAIL_ADDRESS"]}},
20+
],
21+
},
22+
"input": {
23+
"version": 1,
24+
"guardrails": [
2025
{
2126
"name": "Custom Prompt Check",
2227
"config": {

pyproject.toml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,13 @@ readme = "README.md"
66
requires-python = ">=3.11"
77
license = "MIT"
88
authors = [{ name = "OpenAI", email = "[email protected]" }]
9-
dependencies = ["openai>=1.75.0", "pydantic>=2.11.3", "openai-agents>=0.3.3"]
9+
dependencies = [
10+
"openai>=1.75.0",
11+
"pydantic>=2.11.3",
12+
"openai-agents>=0.3.3",
13+
"pip>=25.0.1",
14+
"presidio-analyzer>=2.2.358",
15+
]
1016
classifiers = [
1117
"Typing :: Typed",
1218
"Intended Audience :: Developers",
@@ -25,10 +31,6 @@ examples = [
2531
"pillow>=11.2.1",
2632
"rich>=14.0.0",
2733
]
28-
presidio = [
29-
"pip>=25.0.1", # Required to load spaCy dependency for presidio-analyzer
30-
"presidio-analyzer>=2.2.358",
31-
]
3234
benchmark = [
3335
"numpy>=1.24.0",
3436
"scikit-learn>=1.3.0",

requirements.txt

Lines changed: 193 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,45 +5,232 @@ annotated-types==0.7.0
55
anyio==4.9.0
66
# via
77
# httpx
8+
# mcp
89
# openai
10+
# sse-starlette
11+
# starlette
12+
attrs==25.3.0
13+
# via
14+
# jsonschema
15+
# referencing
16+
blis==1.3.0
17+
# via thinc
18+
catalogue==2.0.10
19+
# via
20+
# spacy
21+
# srsly
22+
# thinc
923
certifi==2025.4.26
1024
# via
1125
# httpcore
1226
# httpx
27+
# requests
28+
charset-normalizer==3.4.3
29+
# via requests
30+
click==8.3.0
31+
# via
32+
# typer
33+
# uvicorn
34+
cloudpathlib==0.22.0
35+
# via weasel
36+
colorama==0.4.6
37+
# via griffe
38+
confection==0.1.5
39+
# via
40+
# thinc
41+
# weasel
42+
cymem==2.0.11
43+
# via
44+
# preshed
45+
# spacy
46+
# thinc
1347
distro==1.9.0
1448
# via openai
49+
filelock==3.19.1
50+
# via tldextract
51+
griffe==1.14.0
52+
# via openai-agents
1553
h11==0.16.0
16-
# via httpcore
54+
# via
55+
# httpcore
56+
# uvicorn
1757
httpcore==1.0.9
1858
# via httpx
1959
httpx==0.28.1
20-
# via openai
60+
# via
61+
# mcp
62+
# openai
63+
httpx-sse==0.4.1
64+
# via mcp
2165
idna==3.10
2266
# via
2367
# anyio
2468
# httpx
69+
# requests
70+
# tldextract
71+
jinja2==3.1.6
72+
# via spacy
2573
jiter==0.9.0
2674
# via openai
27-
openai==1.77.0
75+
jsonschema==4.25.1
76+
# via mcp
77+
jsonschema-specifications==2025.9.1
78+
# via jsonschema
79+
langcodes==3.5.0
80+
# via spacy
81+
language-data==1.3.0
82+
# via langcodes
83+
marisa-trie==1.3.1
84+
# via language-data
85+
markdown-it-py==4.0.0
86+
# via rich
87+
markupsafe==3.0.3
88+
# via jinja2
89+
mcp==1.16.0
90+
# via openai-agents
91+
mdurl==0.1.2
92+
# via markdown-it-py
93+
murmurhash==1.0.13
94+
# via
95+
# preshed
96+
# spacy
97+
# thinc
98+
numpy==2.3.3
99+
# via
100+
# blis
101+
# spacy
102+
# thinc
103+
openai==1.109.1
104+
# via
105+
# guardrails (pyproject.toml)
106+
# openai-agents
107+
openai-agents==0.3.3
108+
# via guardrails (pyproject.toml)
109+
packaging==25.0
110+
# via
111+
# spacy
112+
# thinc
113+
# weasel
114+
phonenumbers==9.0.15
115+
# via presidio-analyzer
116+
pip==25.2
117+
# via guardrails (pyproject.toml)
118+
preshed==3.0.10
119+
# via
120+
# spacy
121+
# thinc
122+
presidio-analyzer==2.2.360
28123
# via guardrails (pyproject.toml)
29124
pydantic==2.11.4
30125
# via
31126
# guardrails (pyproject.toml)
127+
# confection
128+
# mcp
32129
# openai
130+
# openai-agents
131+
# pydantic-settings
132+
# spacy
133+
# thinc
134+
# weasel
33135
pydantic-core==2.33.2
34136
# via pydantic
137+
pydantic-settings==2.11.0
138+
# via mcp
139+
pygments==2.19.2
140+
# via rich
141+
python-dotenv==1.1.1
142+
# via pydantic-settings
143+
python-multipart==0.0.20
144+
# via mcp
145+
pyyaml==6.0.3
146+
# via presidio-analyzer
147+
referencing==0.36.2
148+
# via
149+
# jsonschema
150+
# jsonschema-specifications
151+
regex==2025.9.18
152+
# via presidio-analyzer
153+
requests==2.32.5
154+
# via
155+
# openai-agents
156+
# requests-file
157+
# spacy
158+
# tldextract
159+
# weasel
160+
requests-file==2.1.0
161+
# via tldextract
162+
rich==14.1.0
163+
# via typer
164+
rpds-py==0.27.1
165+
# via
166+
# jsonschema
167+
# referencing
168+
setuptools==80.9.0
169+
# via
170+
# spacy
171+
# thinc
172+
shellingham==1.5.4
173+
# via typer
174+
smart-open==7.3.1
175+
# via weasel
35176
sniffio==1.3.1
36177
# via
37178
# anyio
38179
# openai
180+
spacy==3.8.7
181+
# via presidio-analyzer
182+
spacy-legacy==3.0.12
183+
# via spacy
184+
spacy-loggers==1.0.5
185+
# via spacy
186+
srsly==2.5.1
187+
# via
188+
# confection
189+
# spacy
190+
# thinc
191+
# weasel
192+
sse-starlette==3.0.2
193+
# via mcp
194+
starlette==0.48.0
195+
# via mcp
196+
thinc==8.3.6
197+
# via spacy
198+
tldextract==5.3.0
199+
# via presidio-analyzer
39200
tqdm==4.67.1
40-
# via openai
201+
# via
202+
# openai
203+
# spacy
204+
typer==0.19.2
205+
# via
206+
# spacy
207+
# weasel
208+
types-requests==2.32.4.20250913
209+
# via openai-agents
41210
typing-extensions==4.13.2
42211
# via
43-
# anyio
44212
# openai
213+
# openai-agents
45214
# pydantic
46215
# pydantic-core
216+
# typer
47217
# typing-inspection
48218
typing-inspection==0.4.0
49-
# via pydantic
219+
# via
220+
# pydantic
221+
# pydantic-settings
222+
urllib3==2.5.0
223+
# via
224+
# requests
225+
# types-requests
226+
uvicorn==0.37.0
227+
# via mcp
228+
wasabi==1.1.3
229+
# via
230+
# spacy
231+
# thinc
232+
# weasel
233+
weasel==0.4.1
234+
# via spacy
235+
wrapt==1.17.3
236+
# via smart-open

src/guardrails/checks/text/pii.py

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,10 @@
7777
from collections.abc import Sequence
7878
from dataclasses import dataclass
7979
from enum import Enum
80-
from typing import TYPE_CHECKING, Any, Final
80+
from typing import Any, Final
8181

82+
from presidio_analyzer import AnalyzerEngine, RecognizerResult
83+
from presidio_analyzer.nlp_engine import NlpEngineProvider
8284
from pydantic import BaseModel, ConfigDict, Field
8385

8486
from guardrails.registry import default_spec_registry
@@ -89,27 +91,14 @@
8991

9092
logger = logging.getLogger(__name__)
9193

92-
if TYPE_CHECKING:
93-
from presidio_analyzer import AnalyzerEngine, AnalyzerResult
94-
9594

9695
@functools.lru_cache(maxsize=1)
9796
def _get_analyzer_engine() -> AnalyzerEngine:
9897
"""Return a cached, configured Presidio AnalyzerEngine instance.
9998
10099
Returns:
101100
AnalyzerEngine: Initialized Presidio analyzer engine.
102-
103-
Raises:
104-
ImportError: If required Presidio packages are not installed.
105101
"""
106-
try:
107-
from presidio_analyzer import AnalyzerEngine
108-
from presidio_analyzer.nlp_engine import NlpEngineProvider
109-
except ImportError as e:
110-
logger.error("Failed to import Presidio analyzer: %s", e)
111-
raise ImportError("Presidio analyzer package is required") from e
112-
113102
# Define a smaller NLP configuration
114103
sm_nlp_config: Final[dict[str, Any]] = {
115104
"nlp_engine_name": "spacy",
@@ -226,11 +215,11 @@ class PiiDetectionResult:
226215
227216
Attributes:
228217
mapping (dict[str, list[str]]): Mapping from entity type to list of detected strings.
229-
analyzer_results (Sequence[AnalyzerResult]): Raw analyzer results for position information.
218+
analyzer_results (Sequence[RecognizerResult]): Raw analyzer results for position information.
230219
"""
231220

232221
mapping: dict[str, list[str]]
233-
analyzer_results: Sequence[AnalyzerResult]
222+
analyzer_results: Sequence[RecognizerResult]
234223

235224
def to_dict(self) -> dict[str, list[str]]:
236225
"""Convert the result to a dictionary.

0 commit comments

Comments
 (0)