Universal PII Firewall (UPF) Python SDK
Project description
Universal PII Firewall (UPF)
Production-ready Python package for privacy-first sanitization of text and OCR/image inputs before LLM processing.
universal-pii-firewall is designed for high-recall detection and deterministic redaction with a lightweight core install.
Why UPF
- Multi-layer detection pipeline (deterministic IDs, context, multilingual heuristics, optional ML).
- Text and image workflows through one API surface.
- Zero dependencies for text sanitization — image extras are opt-in.
- In-memory processing model for sensitive content handling.
- Configurable redaction and risk controls for enterprise integration.
Install
Core package:
pip install universal-pii-firewall
Optional extras:
# OCR/image text extraction + image redaction
pip install "universal-pii-firewall[image]"
# Optional face blur for image pipeline
pip install "universal-pii-firewall[face]"
# Optional ML NER layer
pip install "universal-pii-firewall[ml]"
# Dev and release tooling
pip install "universal-pii-firewall[dev]"
Quick Start
Text sanitization
from upf import sanitize_text
text = "Alice Smith paid with 4111-1111-1111-1111 and emailed alice@example.com"
print(sanitize_text(text))
# -> [REDACTED:NAME] paid with [REDACTED:CREDIT_CARD] and emailed [REDACTED:EMAIL]
For a long-form, realistic before/after example (with risk score and detected entities),
run examples/text_example.py --mode detailed.
OCR text sanitization
from upf import sanitize_image
ocr_text = "John Doe IBAN DE89370400440532013000"
print(sanitize_image(ocr_text))
Image bytes sanitization
from upf import sanitize_image_bytes
with open("examples/inputs/1.png", "rb") as f:
image_bytes = f.read()
result = sanitize_image_bytes(
image_bytes,
ocr_text="John Doe paid with 4111 1111 1111 1111 and email john@example.com",
)
print(result.sanitized_text)
print(result.risk_score, result.risk_level)
Optional face blur
from upf import UPFConfig, sanitize_image_bytes
cfg = UPFConfig(blur_faces=True, face_blur_strength=31)
with open("examples/inputs/2.png", "rb") as f:
result = sanitize_image_bytes(
f.read(),
ocr_text="Alice Smith alice@example.com",
config=cfg,
)
Optional signature blur
Detects handwritten signature regions via contour heuristics and blurs them.
Requires the face extra (OpenCV).
from upf import UPFConfig, sanitize_image_bytes
cfg = UPFConfig(blur_signatures=True, signature_blur_strength=31)
with open("examples/inputs/1.png", "rb") as f:
result = sanitize_image_bytes(
f.read(),
ocr_text="Signed by John Doe on 2026-03-06",
config=cfg,
)
Both face and signature blur can be combined:
cfg = UPFConfig(
blur_faces=True,
face_blur_strength=51,
blur_signatures=True,
signature_blur_strength=31,
)
Enable via environment variables in image_example.py --mode detailed:
UPF_BLUR_FACES=true UPF_BLUR_SIGNATURES=true uv run python examples/image_example.py --mode detailed
If you omit ocr_text, install the image extra and ensure Tesseract OCR is available on your system.
Configuration Knobs
Key UPFConfig controls:
- Detection toggles:
redact_names,redact_emails,redact_phones,redact_secrets,redact_addresses,redact_urls,redact_numeric_ids,redact_national_ids - Detector layers:
use_ml_ner,use_multilingual,use_relationship_detector - Image behavior:
blur_faces,face_blur_strength,blur_signatures,signature_blur_strength - Redaction behavior:
redaction_mode(label,mask,partial,pseudonym,skeleton) - Risk policy:
risk_mode,low_threshold,high_threshold,block_high_risk,deterministic_floor_types
Public API Reference
Stable exported interface from upf:
sanitize_textsanitize_text_with_detailssanitize_imagesanitize_image_bytessanitize_image_base64secure_llm_callSecureLLMResultUPFConfigRedactionModePseudonymSessionHighRiskBlockedErrorImageSanitizeResultTextSanitizeResult
Benchmark Methodology and Results
Text benchmark metrics below are from the included dataset and scripts:
- Command:
uv run python benchmarks/run_tests.py - Command:
uv run python benchmarks/run_tests_strict.py - Interpreter: Python 3.11.14
- Measurement date: March 6, 2026
- Dataset size: 74 labeled text cases (
text,multilingual,edge_cases)
Measured results:
| Metric | Value |
|---|---|
| Cases | 74 |
| Precision | 0.9733 |
| Recall | 1.0000 |
| Avg latency (ms) | 0.2495 |
| P95 latency (ms) | 0.3505 |
| Strict F1 | 0.9865 |
Language coverage in this dataset: EN, ES, PL, PT, PT-BR.
Image precision/recall benchmark is not published yet because labeled image sidecar cases are currently absent (benchmarks/run_image_tests.py reports 0 cases).
Showcase Gallery
Sample assets are included under examples/inputs/ and examples/outputs/.
Case 1
| Input | Redacted | Results Panel |
|---|---|---|
Case 2
| Input | Redacted | Results Panel |
|---|---|---|
Case 3
| Input | Redacted | Results Panel |
|---|---|---|
Running Local Examples
From repository root:
uv run python examples/text_example.py --mode quick
uv run python examples/text_example.py --mode detailed
uv run python examples/image_example.py --mode quick
uv run python examples/image_example.py --mode detailed
image_example.py --mode detailed requires the image extra and image inputs in examples/inputs/.
Limitations
- Image benchmark precision/recall is not yet formalized due to missing labeled sidecar cases.
- OCR quality directly affects image-text extraction quality.
- Optional ML detector (
[ml]) depends on external model/runtime availability.
Release Notes
v0.1.0
- First PyPI-ready package layout with flat repository structure.
- Stable public API exports via
upf/__init__.py. - Optional extras separated by capability (
image,face,ml,dev). - Included reproducible text benchmark dataset and scripts.
License
Apache License 2.0.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file universal_pii_firewall-0.1.0.tar.gz.
File metadata
- Download URL: universal_pii_firewall-0.1.0.tar.gz
- Upload date:
- Size: 50.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9d86d901962226a5a5615c2b7d34c49c78467e0b079ee33c76980d703c7ea23a
|
|
| MD5 |
109711c7697e06443d98e43f1a5451e8
|
|
| BLAKE2b-256 |
3da94941bc5c5c20300b6042f2f81585bfe66b89d1f49d084502e05bae383960
|
File details
Details for the file universal_pii_firewall-0.1.0-py3-none-any.whl.
File metadata
- Download URL: universal_pii_firewall-0.1.0-py3-none-any.whl
- Upload date:
- Size: 62.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2b29c2897ddd8a65537d8ff23d258aff3e7a25992bae0b2990f9048ddd0cadf6
|
|
| MD5 |
0cedddf78d3a4cbe56bbfbf5715b8351
|
|
| BLAKE2b-256 |
9421642bcd1aeb7e1c098fcb5d010c430291008e17fbf5f1af46e609012db236
|