pyveil 0.2.2__tar.gz → 0.2.4__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.
- {pyveil-0.2.2 → pyveil-0.2.4}/AGENTS.md +23 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/CHANGELOG.md +28 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/PKG-INFO +152 -4
- {pyveil-0.2.2 → pyveil-0.2.4}/README.md +135 -1
- {pyveil-0.2.2 → pyveil-0.2.4}/docs/README.md +3 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/docs/cookbook.md +200 -8
- {pyveil-0.2.2 → pyveil-0.2.4}/docs/evaluation.html +1 -1
- {pyveil-0.2.2 → pyveil-0.2.4}/docs/index.html +16 -1
- pyveil-0.2.4/docs/integrations/anthropic.md +136 -0
- pyveil-0.2.4/docs/integrations/ollama.md +134 -0
- pyveil-0.2.4/docs/integrations/openai.md +136 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/docs/llms.txt +9 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/docs/manual.html +151 -9
- pyveil-0.2.4/docs/release-checklist.md +57 -0
- pyveil-0.2.4/examples/anthropic.env.example +9 -0
- pyveil-0.2.4/examples/anthropic.example.yaml +12 -0
- pyveil-0.2.4/examples/anthropic.py +6 -0
- pyveil-0.2.4/examples/ollama.env.example +11 -0
- pyveil-0.2.4/examples/ollama.example.yaml +15 -0
- pyveil-0.2.4/examples/ollama.py +10 -0
- pyveil-0.2.4/examples/openai.env.example +9 -0
- pyveil-0.2.4/examples/openai.example.yaml +12 -0
- pyveil-0.2.4/examples/openai.py +6 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/llms.txt +10 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/pyproject.toml +23 -3
- {pyveil-0.2.2 → pyveil-0.2.4}/pyveil/__init__.py +1 -1
- pyveil-0.2.4/pyveil/integrations/_provider.py +356 -0
- pyveil-0.2.4/pyveil/integrations/anthropic.py +266 -0
- pyveil-0.2.4/pyveil/integrations/ollama.py +450 -0
- pyveil-0.2.4/pyveil/integrations/openai.py +254 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/pyveil.egg-info/PKG-INFO +152 -4
- {pyveil-0.2.2 → pyveil-0.2.4}/pyveil.egg-info/SOURCES.txt +20 -0
- pyveil-0.2.4/pyveil.egg-info/requires.txt +47 -0
- pyveil-0.2.4/tests/test_anthropic_example.py +327 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/tests/test_cli.py +16 -1
- pyveil-0.2.4/tests/test_ollama_example.py +381 -0
- pyveil-0.2.4/tests/test_openai_example.py +302 -0
- pyveil-0.2.4/tests/test_provider_contracts.py +142 -0
- pyveil-0.2.2/docs/release-checklist.md +0 -43
- pyveil-0.2.2/pyveil.egg-info/requires.txt +0 -24
- {pyveil-0.2.2 → pyveil-0.2.4}/CONTRIBUTING.md +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/LICENSE +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/MANIFEST.in +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/SECURITY.md +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/docs/detector-provenance.md +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/docs/faq.md +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/docs/guides/index.html +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/docs/guides/mcp-pii-redaction.html +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/docs/guides/python-llm-pii-redaction.html +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/docs/guides/pyveil-vs-presidio.html +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/docs/guides/style.css +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/docs/integrations/logging.md +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/docs/integrations/mcp.md +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/docs/integrations/tracing.md +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/docs/known-limitations.md +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/docs/media/favicon.svg +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/docs/media/pyveil-awesome-demo.gif +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/docs/media/social-preview.html +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/docs/media/social-preview.png +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/docs/redaction-reference.md +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/docs/roadmap.md +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/docs/robots.txt +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/docs/sitemap.xml +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/docs/threat-model.md +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/evaluation/README.md +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/evaluation/corpus.json +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/evaluation/evaluate.py +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/examples/azure_openai.env.example +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/examples/azure_openai.example.yaml +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/examples/azure_openai.py +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/examples/basic_usage.py +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/examples/custom_rules.py +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/examples/fastapi_middleware.py +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/examples/litellm_proxy_filter.py +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/examples/llm_client_boundary.py +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/examples/log_filter.py +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/examples/mcp_server_wrapper.py +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/examples/mcp_tool_result.py +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/examples/memory_write.py +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/examples/openai_agents_guardrail.py +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/examples/redact_json.py +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/pyveil/__main__.py +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/pyveil/cli.py +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/pyveil/constants.py +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/pyveil/core.py +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/pyveil/detectors.py +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/pyveil/exceptions.py +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/pyveil/findings.py +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/pyveil/integrations/__init__.py +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/pyveil/integrations/azure_openai.py +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/pyveil/integrations/logging.py +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/pyveil/integrations/mcp.py +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/pyveil/levels.py +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/pyveil/masker.py +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/pyveil/masking.py +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/pyveil/patterns.py +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/pyveil/placeholders.py +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/pyveil/policy.py +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/pyveil/py.typed +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/pyveil/rules.py +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/pyveil/utils.py +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/pyveil.egg-info/dependency_links.txt +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/pyveil.egg-info/entry_points.txt +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/pyveil.egg-info/top_level.txt +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/pyveil.yaml +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/setup.cfg +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/setup.py +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/tests/__init__.py +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/tests/test_azure_openai_example.py +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/tests/test_custom_rules.py +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/tests/test_masker.py +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/tests/test_patterns.py +0 -0
- {pyveil-0.2.2 → pyveil-0.2.4}/tests/test_utils.py +0 -0
|
@@ -19,6 +19,10 @@ Do not turn pyveil into a general DLP suite, gateway, Presidio clone, or prompt-
|
|
|
19
19
|
- Run CLI demo: `python3 -m pyveil demo`
|
|
20
20
|
- Run CLI locally: `PYVEIL_SECRET=dev-secret python3 -m pyveil redact <file>`
|
|
21
21
|
- Run detector evaluation: `python3 evaluation/evaluate.py --check`
|
|
22
|
+
- Run the OpenAI boundary without a key: `PYVEIL_SECRET=dev-secret OPENAI_MODEL=gpt-5.6-luna python3 -m pyveil.integrations.openai --dry-run`
|
|
23
|
+
- Run the Anthropic boundary without a key: `PYVEIL_SECRET=dev-secret ANTHROPIC_MODEL=claude-haiku-4-5 python3 -m pyveil.integrations.anthropic --dry-run`
|
|
24
|
+
- Run the Ollama boundary without a model call: `PYVEIL_SECRET=dev-secret python3 -m pyveil.integrations.ollama --dry-run`
|
|
25
|
+
- Run offline provider SDK contracts: `uv run --extra openai --extra anthropic --extra test pytest tests/test_provider_contracts.py -m provider_contract --no-cov`
|
|
22
26
|
|
|
23
27
|
## Architecture
|
|
24
28
|
|
|
@@ -72,6 +76,9 @@ This repository includes files meant for coding agents and LLM readers:
|
|
|
72
76
|
- [docs/evaluation.html](docs/evaluation.html)
|
|
73
77
|
- [docs/guides/](docs/guides/)
|
|
74
78
|
- [docs/integrations/mcp.md](docs/integrations/mcp.md)
|
|
79
|
+
- [docs/integrations/openai.md](docs/integrations/openai.md)
|
|
80
|
+
- [docs/integrations/anthropic.md](docs/integrations/anthropic.md)
|
|
81
|
+
- [docs/integrations/ollama.md](docs/integrations/ollama.md)
|
|
75
82
|
- [docs/integrations/logging.md](docs/integrations/logging.md)
|
|
76
83
|
- [docs/integrations/tracing.md](docs/integrations/tracing.md)
|
|
77
84
|
|
|
@@ -88,6 +95,9 @@ Examples:
|
|
|
88
95
|
- [examples/fastapi_middleware.py](examples/fastapi_middleware.py)
|
|
89
96
|
- [examples/litellm_proxy_filter.py](examples/litellm_proxy_filter.py)
|
|
90
97
|
- [examples/azure_openai.py](examples/azure_openai.py)
|
|
98
|
+
- [examples/openai.py](examples/openai.py)
|
|
99
|
+
- [examples/anthropic.py](examples/anthropic.py)
|
|
100
|
+
- [examples/ollama.py](examples/ollama.py)
|
|
91
101
|
|
|
92
102
|
## Development
|
|
93
103
|
|
|
@@ -95,8 +105,15 @@ Examples:
|
|
|
95
105
|
uv run --extra dev ruff check .
|
|
96
106
|
uv run --extra dev mypy pyveil tests
|
|
97
107
|
uv run --extra test pytest
|
|
108
|
+
uv run --extra openai --extra anthropic --extra test \
|
|
109
|
+
pytest tests/test_provider_contracts.py -m provider_contract --no-cov
|
|
98
110
|
```
|
|
99
111
|
|
|
112
|
+
The dependency-free core is tested on Python 3.8 through 3.14. The current
|
|
113
|
+
official OpenAI and Anthropic SDKs require Python 3.9+, so their serialization
|
|
114
|
+
contract matrix covers Python 3.9 through 3.14. Their keyless dry-runs remain
|
|
115
|
+
usable on Python 3.8 because provider SDK imports happen only for live calls.
|
|
116
|
+
|
|
100
117
|
Full local release check:
|
|
101
118
|
|
|
102
119
|
```bash
|
|
@@ -104,6 +121,12 @@ for v in 3.8 3.9 3.10 3.11 3.12 3.13 3.14; do
|
|
|
104
121
|
UV_PROJECT_ENVIRONMENT="/tmp/pyveil-venv-$v" uv run --python "$v" --extra test pytest -q --disable-warnings --no-cov
|
|
105
122
|
done
|
|
106
123
|
|
|
124
|
+
for v in 3.9 3.10 3.11 3.12 3.13 3.14; do
|
|
125
|
+
UV_PROJECT_ENVIRONMENT="/tmp/pyveil-provider-$v" uv run --python "$v" \
|
|
126
|
+
--extra openai --extra anthropic --extra test \
|
|
127
|
+
pytest tests/test_provider_contracts.py -m provider_contract -q --no-cov
|
|
128
|
+
done
|
|
129
|
+
|
|
107
130
|
uv run --extra dev python -m build
|
|
108
131
|
uv run --extra dev python -m twine check dist/*
|
|
109
132
|
```
|
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.2.4 - 2026-07-16
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- Installable OpenAI Responses API and Anthropic Messages API redaction
|
|
8
|
+
templates with env, `.env`, YAML, and keyless dry-run support.
|
|
9
|
+
- Offline contract tests that exercise the official provider SDKs through
|
|
10
|
+
local mock HTTP transports without credentials, network requests, or spend.
|
|
11
|
+
- A Python 3.9 through 3.14 provider-contract CI matrix while preserving the
|
|
12
|
+
dependency-free Python 3.8 through 3.14 core matrix.
|
|
13
|
+
|
|
14
|
+
## 0.2.3 - 2026-07-16
|
|
15
|
+
|
|
16
|
+
Local Ollama boundary release.
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
|
|
20
|
+
- Installable Ollama chat integration with env, `.env`, and YAML configuration,
|
|
21
|
+
a dry-run boundary, response metrics, and configurable context/keep-alive limits.
|
|
22
|
+
- A tested `qwen3.5:4b` local-model recipe sized for a 16GB Apple silicon Mac.
|
|
23
|
+
|
|
24
|
+
### Changed
|
|
25
|
+
|
|
26
|
+
- Added an optional `ollama` dependency group while keeping the core package
|
|
27
|
+
dependency-free.
|
|
28
|
+
- Expanded the README, Cookbook, web Manual, and agent-facing navigation with
|
|
29
|
+
a complete local-model request path and measured memory/latency trade-offs.
|
|
30
|
+
|
|
3
31
|
## 0.2.2 - 2026-07-15
|
|
4
32
|
|
|
5
33
|
Azure OpenAI adoption release.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: pyveil
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.4
|
|
4
4
|
Summary: Local PII and secret redaction for Python LLM apps, AI agents, tool calls, and MCP
|
|
5
5
|
Author-email: Hyeon Sang Jeon <wingnut0310@gmail.com>
|
|
6
6
|
Maintainer-email: Hyeon Sang Jeon <wingnut0310@gmail.com>
|
|
@@ -36,9 +36,21 @@ Requires-Python: >=3.8
|
|
|
36
36
|
Description-Content-Type: text/markdown
|
|
37
37
|
License-File: LICENSE
|
|
38
38
|
Provides-Extra: azure-openai
|
|
39
|
-
Requires-Dist: openai
|
|
39
|
+
Requires-Dist: openai<3.0.0,>=1.66.0; extra == "azure-openai"
|
|
40
40
|
Requires-Dist: python-dotenv>=1.0.0; extra == "azure-openai"
|
|
41
41
|
Requires-Dist: PyYAML>=6.0.0; extra == "azure-openai"
|
|
42
|
+
Provides-Extra: openai
|
|
43
|
+
Requires-Dist: openai<3.0.0,>=2.45.0; python_version >= "3.9" and extra == "openai"
|
|
44
|
+
Requires-Dist: python-dotenv>=1.0.0; extra == "openai"
|
|
45
|
+
Requires-Dist: PyYAML>=6.0.0; extra == "openai"
|
|
46
|
+
Provides-Extra: anthropic
|
|
47
|
+
Requires-Dist: anthropic<1.0.0,>=0.116.0; python_version >= "3.9" and extra == "anthropic"
|
|
48
|
+
Requires-Dist: python-dotenv>=1.0.0; extra == "anthropic"
|
|
49
|
+
Requires-Dist: PyYAML>=6.0.0; extra == "anthropic"
|
|
50
|
+
Provides-Extra: ollama
|
|
51
|
+
Requires-Dist: ollama<1.0.0,>=0.6.2; extra == "ollama"
|
|
52
|
+
Requires-Dist: python-dotenv>=1.0.0; extra == "ollama"
|
|
53
|
+
Requires-Dist: PyYAML>=6.0.0; extra == "ollama"
|
|
42
54
|
Provides-Extra: dev
|
|
43
55
|
Requires-Dist: build>=1.2.0; extra == "dev"
|
|
44
56
|
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
@@ -47,7 +59,9 @@ Requires-Dist: black>=23.0.0; extra == "dev"
|
|
|
47
59
|
Requires-Dist: ruff>=0.1.0; extra == "dev"
|
|
48
60
|
Requires-Dist: twine>=5.0.0; extra == "dev"
|
|
49
61
|
Requires-Dist: mypy>=1.0.0; extra == "dev"
|
|
50
|
-
Requires-Dist:
|
|
62
|
+
Requires-Dist: ollama<1.0.0,>=0.6.2; extra == "dev"
|
|
63
|
+
Requires-Dist: openai<3.0.0,>=2.45.0; python_version >= "3.9" and extra == "dev"
|
|
64
|
+
Requires-Dist: anthropic<1.0.0,>=0.116.0; python_version >= "3.9" and extra == "dev"
|
|
51
65
|
Requires-Dist: python-dotenv>=1.0.0; extra == "dev"
|
|
52
66
|
Requires-Dist: PyYAML>=6.0.0; extra == "dev"
|
|
53
67
|
Requires-Dist: types-PyYAML>=6.0.0; extra == "dev"
|
|
@@ -140,6 +154,138 @@ response = call_llm(safe.data) # Your provider SDK call
|
|
|
140
154
|
The provider receives the same list and dictionary shape, with sensitive values
|
|
141
155
|
replaced before serialization or transmission.
|
|
142
156
|
|
|
157
|
+
## OpenAI And Claude: Keyless Contract-Tested Templates
|
|
158
|
+
|
|
159
|
+
Install provider-specific templates without adding either SDK to pyveil's
|
|
160
|
+
zero-dependency core:
|
|
161
|
+
|
|
162
|
+
```bash
|
|
163
|
+
pip install "pyveil[openai]" # OpenAI Responses API
|
|
164
|
+
pip install "pyveil[anthropic]" # Claude Messages API
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Both integrations redact locally at the final SDK boundary and return the exact
|
|
168
|
+
provider input for inspection:
|
|
169
|
+
|
|
170
|
+
```python
|
|
171
|
+
from pyveil.integrations.openai import ask_openai, load_settings
|
|
172
|
+
|
|
173
|
+
settings = load_settings()
|
|
174
|
+
result = ask_openai(
|
|
175
|
+
"Write a follow-up for alice@example.com or 010-1234-5678.",
|
|
176
|
+
settings,
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
print(result.redacted_input) # exact client.responses.create(...) input
|
|
180
|
+
print(result.output_text)
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
```python
|
|
184
|
+
from pyveil.integrations.anthropic import ask_anthropic, load_settings
|
|
185
|
+
|
|
186
|
+
settings = load_settings()
|
|
187
|
+
result = ask_anthropic(
|
|
188
|
+
"Write a follow-up for alice@example.com or 010-1234-5678.",
|
|
189
|
+
settings,
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
print(result.redacted_input) # exact client.messages.create(...) content
|
|
193
|
+
print(result.output_text)
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
No API key is needed to prove either boundary:
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
PYVEIL_SECRET=docs-demo-secret OPENAI_MODEL=gpt-5.6-luna \
|
|
200
|
+
python -m pyveil.integrations.openai --dry-run
|
|
201
|
+
|
|
202
|
+
PYVEIL_SECRET=docs-demo-secret ANTHROPIC_MODEL=claude-haiku-4-5 \
|
|
203
|
+
python -m pyveil.integrations.anthropic --dry-run
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
```text
|
|
207
|
+
sent-to-openai: ... [EMAIL:17c25f8a4fe3] ... [PHONE:3f6dc5a3c9f3].
|
|
208
|
+
sent-to-anthropic: ... [EMAIL:0b77abd1b26b] ... [PHONE:ec56e2456ba2].
|
|
209
|
+
provider-response: skipped (--dry-run)
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
The repository also exercises the real official SDKs through local mock HTTP
|
|
213
|
+
transports and asserts against the serialized `/v1/responses` and `/v1/messages`
|
|
214
|
+
JSON bodies. These tests use no credentials, make no network requests, and
|
|
215
|
+
cannot incur provider spend. A live paid API call has **not** been claimed.
|
|
216
|
+
Historical provider models are not a free fallback and may be retired; keep the
|
|
217
|
+
model ID configurable and use dry-run or mock contracts for cost-free checks.
|
|
218
|
+
|
|
219
|
+
Current OpenAI and Anthropic SDKs require Python 3.9+. The pyveil core and both
|
|
220
|
+
keyless dry-run paths remain compatible with Python 3.8 through 3.14. Use the
|
|
221
|
+
checked-in [OpenAI guide](docs/integrations/openai.md) and
|
|
222
|
+
[Anthropic / Claude guide](docs/integrations/anthropic.md) for configuration,
|
|
223
|
+
offline verification, and boundary notes.
|
|
224
|
+
|
|
225
|
+
## Ollama: Local End To End
|
|
226
|
+
|
|
227
|
+
Run a local model behind the same redaction boundary. The optional integration
|
|
228
|
+
uses Ollama's official Python client and defaults to `qwen3.5:4b`, a Q4_K_M
|
|
229
|
+
4.7B model that fits comfortably on a 16GB Apple silicon Mac with a 4K context:
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
pip install "pyveil[ollama]"
|
|
233
|
+
ollama pull qwen3.5:4b
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
```python
|
|
237
|
+
from pyveil.integrations.ollama import ask_ollama, load_settings
|
|
238
|
+
|
|
239
|
+
settings = load_settings() # OLLAMA_* + PYVEIL_* environment variables
|
|
240
|
+
result = ask_ollama(
|
|
241
|
+
"Write a follow-up for alice@example.com or 010-1234-5678.",
|
|
242
|
+
settings,
|
|
243
|
+
)
|
|
244
|
+
|
|
245
|
+
print(result.redacted_input) # The exact prompt sent to Ollama
|
|
246
|
+
print(result.output_text) # The local model response
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
Prove the boundary without loading a model:
|
|
250
|
+
|
|
251
|
+
```bash
|
|
252
|
+
PYVEIL_SECRET=docs-demo-secret \
|
|
253
|
+
python -m pyveil.integrations.ollama --dry-run
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
```text
|
|
257
|
+
mode: dry-run
|
|
258
|
+
model: qwen3.5:4b
|
|
259
|
+
host: http://127.0.0.1:11434
|
|
260
|
+
sent-to-ollama: Write a one-sentence support follow-up for [EMAIL:71c6727a7fa2] or [PHONE:b4b889df07ce].
|
|
261
|
+
findings: EMAIL=1, PHONE=1
|
|
262
|
+
ollama-response: skipped (--dry-run)
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
For a live local call, set `PYVEIL_SECRET` and run the module. Configuration
|
|
266
|
+
priority is process environment, `.env`, YAML, then defaults:
|
|
267
|
+
|
|
268
|
+
```bash
|
|
269
|
+
PYVEIL_SECRET=a-long-random-hmac-secret \
|
|
270
|
+
python -m pyveil.integrations.ollama
|
|
271
|
+
|
|
272
|
+
python -m pyveil.integrations.ollama \
|
|
273
|
+
--config examples/ollama.example.yaml --env-file .env
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
The checked-in [`.env` template](examples/ollama.env.example) and
|
|
277
|
+
[YAML template](examples/ollama.example.yaml) expose model, host, context,
|
|
278
|
+
output length, temperature, timeout, and keep-alive. pyveil caps the default
|
|
279
|
+
context at 4096 and uses `keep_alive=0`, so one-shot calls release model memory;
|
|
280
|
+
set `OLLAMA_KEEP_ALIVE=5m` for faster repeated calls.
|
|
281
|
+
|
|
282
|
+
Observed on this project's M1 Mac mini with 16GB memory and Ollama 0.31.2:
|
|
283
|
+
`qwen3.5:4b` used about 3.2GB at a 4096-token context, a cold request took
|
|
284
|
+
8.1 seconds, and a warm request took 1.3 seconds. These are local measurements,
|
|
285
|
+
not portable performance guarantees. See the
|
|
286
|
+
[Ollama integration guide](docs/integrations/ollama.md) for the full setup and
|
|
287
|
+
memory trade-offs.
|
|
288
|
+
|
|
143
289
|
## Azure OpenAI: End To End
|
|
144
290
|
|
|
145
291
|
Install the optional Azure example dependencies, then load configuration from
|
|
@@ -226,7 +372,7 @@ evaluator:
|
|
|
226
372
|
python evaluation/evaluate.py --check
|
|
227
373
|
```
|
|
228
374
|
|
|
229
|
-
For corpus v1, pyveil 0.2.
|
|
375
|
+
For corpus v1, pyveil 0.2.4 matches all 36 expected findings across 39 cases
|
|
230
376
|
(33 positive, 6 negative), with no corpus false positives, false negatives,
|
|
231
377
|
labeled-value leaks, or non-empty `Finding.raw` values.
|
|
232
378
|
|
|
@@ -368,6 +514,8 @@ is parsed and traversed structurally.
|
|
|
368
514
|
| --- | --- |
|
|
369
515
|
| Any LLM provider | [Provider-neutral client wrapper](https://github.com/hyeonsangjeon/pyveil/blob/main/examples/llm_client_boundary.py) |
|
|
370
516
|
| OpenAI Agents SDK | [Input guardrail example](https://github.com/hyeonsangjeon/pyveil/blob/main/examples/openai_agents_guardrail.py) |
|
|
517
|
+
| OpenAI Responses API | [Installable integration](https://github.com/hyeonsangjeon/pyveil/blob/main/pyveil/integrations/openai.py) and [keyless contract guide](https://github.com/hyeonsangjeon/pyveil/blob/main/docs/integrations/openai.md) |
|
|
518
|
+
| Anthropic / Claude | [Installable integration](https://github.com/hyeonsangjeon/pyveil/blob/main/pyveil/integrations/anthropic.py) and [keyless contract guide](https://github.com/hyeonsangjeon/pyveil/blob/main/docs/integrations/anthropic.md) |
|
|
371
519
|
| Azure OpenAI | [Runnable env/YAML integration](https://github.com/hyeonsangjeon/pyveil/blob/main/pyveil/integrations/azure_openai.py) and [short example](https://github.com/hyeonsangjeon/pyveil/blob/main/examples/azure_openai.py) |
|
|
372
520
|
| LiteLLM | [Proxy filter example](https://github.com/hyeonsangjeon/pyveil/blob/main/examples/litellm_proxy_filter.py) |
|
|
373
521
|
| FastAPI | [Request middleware example](https://github.com/hyeonsangjeon/pyveil/blob/main/examples/fastapi_middleware.py) |
|
|
@@ -81,6 +81,138 @@ response = call_llm(safe.data) # Your provider SDK call
|
|
|
81
81
|
The provider receives the same list and dictionary shape, with sensitive values
|
|
82
82
|
replaced before serialization or transmission.
|
|
83
83
|
|
|
84
|
+
## OpenAI And Claude: Keyless Contract-Tested Templates
|
|
85
|
+
|
|
86
|
+
Install provider-specific templates without adding either SDK to pyveil's
|
|
87
|
+
zero-dependency core:
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
pip install "pyveil[openai]" # OpenAI Responses API
|
|
91
|
+
pip install "pyveil[anthropic]" # Claude Messages API
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Both integrations redact locally at the final SDK boundary and return the exact
|
|
95
|
+
provider input for inspection:
|
|
96
|
+
|
|
97
|
+
```python
|
|
98
|
+
from pyveil.integrations.openai import ask_openai, load_settings
|
|
99
|
+
|
|
100
|
+
settings = load_settings()
|
|
101
|
+
result = ask_openai(
|
|
102
|
+
"Write a follow-up for alice@example.com or 010-1234-5678.",
|
|
103
|
+
settings,
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
print(result.redacted_input) # exact client.responses.create(...) input
|
|
107
|
+
print(result.output_text)
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
```python
|
|
111
|
+
from pyveil.integrations.anthropic import ask_anthropic, load_settings
|
|
112
|
+
|
|
113
|
+
settings = load_settings()
|
|
114
|
+
result = ask_anthropic(
|
|
115
|
+
"Write a follow-up for alice@example.com or 010-1234-5678.",
|
|
116
|
+
settings,
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
print(result.redacted_input) # exact client.messages.create(...) content
|
|
120
|
+
print(result.output_text)
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
No API key is needed to prove either boundary:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
PYVEIL_SECRET=docs-demo-secret OPENAI_MODEL=gpt-5.6-luna \
|
|
127
|
+
python -m pyveil.integrations.openai --dry-run
|
|
128
|
+
|
|
129
|
+
PYVEIL_SECRET=docs-demo-secret ANTHROPIC_MODEL=claude-haiku-4-5 \
|
|
130
|
+
python -m pyveil.integrations.anthropic --dry-run
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
```text
|
|
134
|
+
sent-to-openai: ... [EMAIL:17c25f8a4fe3] ... [PHONE:3f6dc5a3c9f3].
|
|
135
|
+
sent-to-anthropic: ... [EMAIL:0b77abd1b26b] ... [PHONE:ec56e2456ba2].
|
|
136
|
+
provider-response: skipped (--dry-run)
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
The repository also exercises the real official SDKs through local mock HTTP
|
|
140
|
+
transports and asserts against the serialized `/v1/responses` and `/v1/messages`
|
|
141
|
+
JSON bodies. These tests use no credentials, make no network requests, and
|
|
142
|
+
cannot incur provider spend. A live paid API call has **not** been claimed.
|
|
143
|
+
Historical provider models are not a free fallback and may be retired; keep the
|
|
144
|
+
model ID configurable and use dry-run or mock contracts for cost-free checks.
|
|
145
|
+
|
|
146
|
+
Current OpenAI and Anthropic SDKs require Python 3.9+. The pyveil core and both
|
|
147
|
+
keyless dry-run paths remain compatible with Python 3.8 through 3.14. Use the
|
|
148
|
+
checked-in [OpenAI guide](docs/integrations/openai.md) and
|
|
149
|
+
[Anthropic / Claude guide](docs/integrations/anthropic.md) for configuration,
|
|
150
|
+
offline verification, and boundary notes.
|
|
151
|
+
|
|
152
|
+
## Ollama: Local End To End
|
|
153
|
+
|
|
154
|
+
Run a local model behind the same redaction boundary. The optional integration
|
|
155
|
+
uses Ollama's official Python client and defaults to `qwen3.5:4b`, a Q4_K_M
|
|
156
|
+
4.7B model that fits comfortably on a 16GB Apple silicon Mac with a 4K context:
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
pip install "pyveil[ollama]"
|
|
160
|
+
ollama pull qwen3.5:4b
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
```python
|
|
164
|
+
from pyveil.integrations.ollama import ask_ollama, load_settings
|
|
165
|
+
|
|
166
|
+
settings = load_settings() # OLLAMA_* + PYVEIL_* environment variables
|
|
167
|
+
result = ask_ollama(
|
|
168
|
+
"Write a follow-up for alice@example.com or 010-1234-5678.",
|
|
169
|
+
settings,
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
print(result.redacted_input) # The exact prompt sent to Ollama
|
|
173
|
+
print(result.output_text) # The local model response
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Prove the boundary without loading a model:
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
PYVEIL_SECRET=docs-demo-secret \
|
|
180
|
+
python -m pyveil.integrations.ollama --dry-run
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
```text
|
|
184
|
+
mode: dry-run
|
|
185
|
+
model: qwen3.5:4b
|
|
186
|
+
host: http://127.0.0.1:11434
|
|
187
|
+
sent-to-ollama: Write a one-sentence support follow-up for [EMAIL:71c6727a7fa2] or [PHONE:b4b889df07ce].
|
|
188
|
+
findings: EMAIL=1, PHONE=1
|
|
189
|
+
ollama-response: skipped (--dry-run)
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
For a live local call, set `PYVEIL_SECRET` and run the module. Configuration
|
|
193
|
+
priority is process environment, `.env`, YAML, then defaults:
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
PYVEIL_SECRET=a-long-random-hmac-secret \
|
|
197
|
+
python -m pyveil.integrations.ollama
|
|
198
|
+
|
|
199
|
+
python -m pyveil.integrations.ollama \
|
|
200
|
+
--config examples/ollama.example.yaml --env-file .env
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
The checked-in [`.env` template](examples/ollama.env.example) and
|
|
204
|
+
[YAML template](examples/ollama.example.yaml) expose model, host, context,
|
|
205
|
+
output length, temperature, timeout, and keep-alive. pyveil caps the default
|
|
206
|
+
context at 4096 and uses `keep_alive=0`, so one-shot calls release model memory;
|
|
207
|
+
set `OLLAMA_KEEP_ALIVE=5m` for faster repeated calls.
|
|
208
|
+
|
|
209
|
+
Observed on this project's M1 Mac mini with 16GB memory and Ollama 0.31.2:
|
|
210
|
+
`qwen3.5:4b` used about 3.2GB at a 4096-token context, a cold request took
|
|
211
|
+
8.1 seconds, and a warm request took 1.3 seconds. These are local measurements,
|
|
212
|
+
not portable performance guarantees. See the
|
|
213
|
+
[Ollama integration guide](docs/integrations/ollama.md) for the full setup and
|
|
214
|
+
memory trade-offs.
|
|
215
|
+
|
|
84
216
|
## Azure OpenAI: End To End
|
|
85
217
|
|
|
86
218
|
Install the optional Azure example dependencies, then load configuration from
|
|
@@ -167,7 +299,7 @@ evaluator:
|
|
|
167
299
|
python evaluation/evaluate.py --check
|
|
168
300
|
```
|
|
169
301
|
|
|
170
|
-
For corpus v1, pyveil 0.2.
|
|
302
|
+
For corpus v1, pyveil 0.2.4 matches all 36 expected findings across 39 cases
|
|
171
303
|
(33 positive, 6 negative), with no corpus false positives, false negatives,
|
|
172
304
|
labeled-value leaks, or non-empty `Finding.raw` values.
|
|
173
305
|
|
|
@@ -309,6 +441,8 @@ is parsed and traversed structurally.
|
|
|
309
441
|
| --- | --- |
|
|
310
442
|
| Any LLM provider | [Provider-neutral client wrapper](https://github.com/hyeonsangjeon/pyveil/blob/main/examples/llm_client_boundary.py) |
|
|
311
443
|
| OpenAI Agents SDK | [Input guardrail example](https://github.com/hyeonsangjeon/pyveil/blob/main/examples/openai_agents_guardrail.py) |
|
|
444
|
+
| OpenAI Responses API | [Installable integration](https://github.com/hyeonsangjeon/pyveil/blob/main/pyveil/integrations/openai.py) and [keyless contract guide](https://github.com/hyeonsangjeon/pyveil/blob/main/docs/integrations/openai.md) |
|
|
445
|
+
| Anthropic / Claude | [Installable integration](https://github.com/hyeonsangjeon/pyveil/blob/main/pyveil/integrations/anthropic.py) and [keyless contract guide](https://github.com/hyeonsangjeon/pyveil/blob/main/docs/integrations/anthropic.md) |
|
|
312
446
|
| Azure OpenAI | [Runnable env/YAML integration](https://github.com/hyeonsangjeon/pyveil/blob/main/pyveil/integrations/azure_openai.py) and [short example](https://github.com/hyeonsangjeon/pyveil/blob/main/examples/azure_openai.py) |
|
|
313
447
|
| LiteLLM | [Proxy filter example](https://github.com/hyeonsangjeon/pyveil/blob/main/examples/litellm_proxy_filter.py) |
|
|
314
448
|
| FastAPI | [Request middleware example](https://github.com/hyeonsangjeon/pyveil/blob/main/examples/fastapi_middleware.py) |
|
|
@@ -12,6 +12,9 @@ Start with:
|
|
|
12
12
|
- [Threat model](threat-model.md)
|
|
13
13
|
- [FAQ](faq.md)
|
|
14
14
|
- [Cookbook](cookbook.md)
|
|
15
|
+
- [OpenAI keyless and live integration](integrations/openai.md)
|
|
16
|
+
- [Anthropic / Claude keyless and live integration](integrations/anthropic.md)
|
|
17
|
+
- [Ollama local-model integration](integrations/ollama.md)
|
|
15
18
|
- [Azure OpenAI env/YAML integration](../pyveil/integrations/azure_openai.py)
|
|
16
19
|
- [Redaction reference](redaction-reference.md)
|
|
17
20
|
- [Known limitations](known-limitations.md)
|