|
| 1 | +# DataFog |
| 2 | + |
| 3 | +Fast PII detection and anonymization, built in Rust with Python and WASM bindings. |
| 4 | + |
| 5 | +DataFog detects structured PII (emails, phone numbers, SSNs, credit cards, IPs, dates of birth, ZIP codes) using compiled regex patterns, and optionally detects soft PII (names, organizations, addresses) using a GLiNER ONNX model via NER. The regex engine runs in microseconds per kilobyte with zero external dependencies. |
| 6 | + |
| 7 | +## Prerequisites |
| 8 | + |
| 9 | +- **Rust** (stable) — install via [rustup](https://rustup.rs/) |
| 10 | +- **Python 3.9+** — for the Python bindings |
| 11 | +- **maturin** — for building the Rust-to-Python bridge |
| 12 | + |
| 13 | +## Quick start (Python) |
| 14 | + |
| 15 | +```bash |
| 16 | +git clone https://github.com/DataFog/datafog.git |
| 17 | +cd datafog |
| 18 | + |
| 19 | +python3 -m venv .venv |
| 20 | +source .venv/bin/activate # Windows: .venv\Scripts\activate |
| 21 | +pip install maturin pytest |
| 22 | + |
| 23 | +maturin develop # builds Rust, installs editable Python package |
| 24 | +pytest -v # runs the test suite |
| 25 | +``` |
| 26 | + |
| 27 | +Then in Python: |
| 28 | + |
| 29 | +```python |
| 30 | +from datafog import DataFog, detect, anonymize_text |
| 31 | + |
| 32 | +# Detect PII |
| 33 | +entities = detect("Contact john@example.com or call 555-123-4567") |
| 34 | +# [{"type": "EMAIL", "value": "john@example.com", "start": 8, "end": 24, "score": 1.0}, |
| 35 | +# {"type": "PHONE", "value": "555-123-4567", "start": 33, "end": 45, "score": 1.0}] |
| 36 | + |
| 37 | +# Anonymize |
| 38 | +clean = anonymize_text("SSN is 123-45-6789", method="redact") |
| 39 | +# "SSN is [REDACTED]" |
| 40 | + |
| 41 | +# Class API with batch support |
| 42 | +fog = DataFog() |
| 43 | +results = fog.detect_batch(["john@test.com", "555-123-4567", "no pii here"]) |
| 44 | +``` |
| 45 | + |
| 46 | +## Quick start (Rust) |
| 47 | + |
| 48 | +Add to your `Cargo.toml`: |
| 49 | + |
| 50 | +```toml |
| 51 | +[dependencies] |
| 52 | +datafog-core = "0.1" |
| 53 | +``` |
| 54 | + |
| 55 | +```rust |
| 56 | +use datafog_core::DataFog; |
| 57 | +use datafog_core::anonymizer::AnonymizeMethod; |
| 58 | + |
| 59 | +let fog = DataFog::new(); |
| 60 | +let result = fog.detect("Contact john@example.com"); |
| 61 | +println!("{:?}", result.spans); |
| 62 | + |
| 63 | +let anon = fog.anonymize("SSN is 123-45-6789", AnonymizeMethod::Redact); |
| 64 | +assert_eq!(anon.text, "SSN is [REDACTED]"); |
| 65 | +``` |
| 66 | + |
| 67 | +## NER engine (optional) |
| 68 | + |
| 69 | +The NER engine uses a [GLiNER](https://github.com/urchade/GLiNER) ONNX model to detect soft PII that regex can't catch: person names, organizations, locations, addresses, and more. It runs both regex and NER, then merges the results. |
| 70 | + |
| 71 | +Building with NER pulls in `gline-rs` + ONNX Runtime (~50 MB binary size increase). |
| 72 | + |
| 73 | +```bash |
| 74 | +# Build the Python package with NER + model auto-download |
| 75 | +maturin develop --features full |
| 76 | +``` |
| 77 | + |
| 78 | +```python |
| 79 | +from datafog import DataFog, has_ner_support |
| 80 | + |
| 81 | +if has_ner_support(): |
| 82 | + fog = DataFog(engine="ner") # downloads ~50 MB model on first use |
| 83 | + entities = fog.detect("John Smith works at Acme Corp in Paris") |
| 84 | + # detects PERSON, ORGANIZATION, LOCATION in addition to regex entities |
| 85 | +``` |
| 86 | + |
| 87 | +You can also point to a local model directory: |
| 88 | + |
| 89 | +```python |
| 90 | +fog = DataFog(engine="ner", model="/path/to/model/dir") |
| 91 | +``` |
| 92 | + |
| 93 | +The model directory must contain `tokenizer.json` and `model.onnx`. |
| 94 | + |
| 95 | +### Entity types |
| 96 | + |
| 97 | +| Engine | Entity types | |
| 98 | +|--------|-------------| |
| 99 | +| Regex | `EMAIL`, `PHONE`, `SSN`, `CREDIT_CARD`, `IP_ADDRESS`, `DOB`, `ZIP` | |
| 100 | +| NER | `PERSON`, `ORGANIZATION`, `LOCATION`, `ADDRESS`, `MEDICAL_RECORD_NUMBER`, `ACCOUNT_NUMBER`, `LICENSE_NUMBER`, `PASSPORT_NUMBER`, `URL` | |
| 101 | + |
| 102 | +When both engines are active, all entity types are available. |
| 103 | + |
| 104 | +## Anonymization methods |
| 105 | + |
| 106 | +```python |
| 107 | +from datafog import anonymize_text |
| 108 | + |
| 109 | +anonymize_text("Email: john@test.com", method="redact") # "Email: [REDACTED]" |
| 110 | +anonymize_text("Email: john@test.com", method="replace") # "Email: [EMAIL_1]" |
| 111 | +anonymize_text("Email: john@test.com", method="hash") # "Email: a1b2c3d4..." |
| 112 | +``` |
| 113 | + |
| 114 | +Available methods: `redact`, `replace`, `hash` (SHA-256), `hash_md5`, `hash_sha3`. |
| 115 | + |
| 116 | +## WASM |
| 117 | + |
| 118 | +The WASM target provides regex-only detection for browser and edge environments. |
| 119 | + |
| 120 | +```bash |
| 121 | +# Requires wasm-pack: https://rustwasm.github.io/wasm-pack/installer/ |
| 122 | +wasm-pack build crates/datafog-wasm --target web |
| 123 | +``` |
| 124 | + |
| 125 | +A demo page is included at `crates/datafog-wasm/demo/index.html`. |
| 126 | + |
| 127 | +## Project structure |
| 128 | + |
| 129 | +``` |
| 130 | +datafog/ |
| 131 | +├── crates/ |
| 132 | +│ ├── datafog-core/ # Pure Rust library (regex, NER, anonymizer, cascade) |
| 133 | +│ ├── datafog-python/ # PyO3 bindings |
| 134 | +│ └── datafog-wasm/ # wasm-bindgen bindings (regex-only) |
| 135 | +├── python/datafog/ # Python package source + type stubs |
| 136 | +├── tests/ # Python integration tests |
| 137 | +├── pyproject.toml # maturin build config |
| 138 | +└── Cargo.toml # Workspace root |
| 139 | +``` |
| 140 | + |
| 141 | +## Feature flags (Rust) |
| 142 | + |
| 143 | +| Flag | What it adds | Dependencies | |
| 144 | +|------|-------------|-------------| |
| 145 | +| `default` | Regex-only detection | None beyond `regex`, `serde` | |
| 146 | +| `ner` | GLiNER NER engine | `gline-rs`, `ort` | |
| 147 | +| `model-download` | Auto-download models from HuggingFace | `reqwest`, `dirs` | |
| 148 | +| `parallel` | Rayon-based batch parallelism | `rayon` | |
| 149 | +| `ner-cuda` | CUDA GPU acceleration for NER | (implies `ner`) | |
| 150 | +| `ner-coreml` | Apple CoreML acceleration for NER | (implies `ner`) | |
| 151 | + |
| 152 | +## Development |
| 153 | + |
| 154 | +```bash |
| 155 | +# Run Rust tests |
| 156 | +cargo test --workspace |
| 157 | + |
| 158 | +# Run clippy and check formatting |
| 159 | +cargo clippy --workspace -- -D warnings |
| 160 | +cargo fmt --all -- --check |
| 161 | + |
| 162 | +# Run benchmarks |
| 163 | +cargo bench --package datafog-core |
| 164 | + |
| 165 | +# Build and test Python |
| 166 | +source .venv/bin/activate |
| 167 | +maturin develop |
| 168 | +pytest -v |
| 169 | +``` |
| 170 | + |
| 171 | +## License |
| 172 | + |
| 173 | +Apache 2.0 |
0 commit comments