datafog-core 0.4.4__tar.gz → 0.4.5b2__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.
Files changed (74) hide show
  1. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/Cargo.lock +5 -4
  2. datafog_core-0.4.5b2/PKG-INFO +246 -0
  3. datafog_core-0.4.5b2/README.md +212 -0
  4. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/bindings/python/Cargo.toml +3 -2
  5. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/bindings/python/src/lib.rs +7 -7
  6. datafog_core-0.4.5b2/bindings/python/src/models.rs +139 -0
  7. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/Cargo.toml +5 -1
  8. datafog_core-0.4.5b2/crates/core/README.md +212 -0
  9. datafog_core-0.4.5b2/crates/core/src/api_key.rs +172 -0
  10. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/src/credential_uri.rs +125 -17
  11. datafog_core-0.4.5b2/crates/core/src/jwt.rs +169 -0
  12. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/src/lib.rs +833 -124
  13. datafog_core-0.4.5b2/crates/core/src/models/gliner2-lock.json +35 -0
  14. datafog_core-0.4.5b2/crates/core/src/models/gliner2.rs +352 -0
  15. datafog_core-0.4.5b2/crates/core/src/models/process.rs +192 -0
  16. datafog_core-0.4.5b2/crates/core/src/models/tests.rs +336 -0
  17. datafog_core-0.4.5b2/crates/core/src/models.rs +984 -0
  18. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/src/offsets.rs +17 -3
  19. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/src/structured.rs +49 -34
  20. datafog_core-0.4.5b2/crates/core/src/uuid.rs +91 -0
  21. datafog_core-0.4.5b2/crates/core/tests/model_datafog.rs +44 -0
  22. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/pyproject.toml +14 -1
  23. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/python/datafog_core/__init__.py +8 -0
  24. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/python/datafog_core/__init__.pyi +60 -0
  25. datafog_core-0.4.5b2/python/datafog_core/_gliner2_worker.py +91 -0
  26. datafog_core-0.4.4/PKG-INFO +0 -382
  27. datafog_core-0.4.4/README.md +0 -358
  28. datafog_core-0.4.4/crates/core/README.md +0 -358
  29. datafog_core-0.4.4/crates/core/src/api_key.rs +0 -66
  30. datafog_core-0.4.4/crates/core/src/jwt.rs +0 -66
  31. datafog_core-0.4.4/crates/core/src/uuid.rs +0 -42
  32. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/Cargo.toml +0 -0
  33. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/bindings/python/tests/api_key_conformance.py +0 -0
  34. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/bindings/python/tests/bearer_token_conformance.py +0 -0
  35. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/bindings/python/tests/capabilities_conformance.py +0 -0
  36. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/bindings/python/tests/credential_overlap_conformance.py +0 -0
  37. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/bindings/python/tests/credential_uri_conformance.py +0 -0
  38. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/bindings/python/tests/email_context_conformance.py +0 -0
  39. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/bindings/python/tests/german_conformance.py +0 -0
  40. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/bindings/python/tests/jwt_conformance.py +0 -0
  41. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/bindings/python/tests/npi_conformance.py +0 -0
  42. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/bindings/python/tests/private_key_conformance.py +0 -0
  43. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/bindings/python/tests/requirements-typing.txt +0 -0
  44. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/bindings/python/tests/synthetic_fixtures.py +0 -0
  45. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/bindings/python/tests/test_installed.py +0 -0
  46. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/bindings/python/tests/test_python49_integration.py +0 -0
  47. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/bindings/python/tests/test_typing.py +0 -0
  48. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/bindings/python/tests/us_routing_number_conformance.py +0 -0
  49. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/bindings/python/tests/uuid_conformance.py +0 -0
  50. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/examples/german_benchmark.rs +0 -0
  51. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/examples/scan_benchmark.rs +0 -0
  52. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/src/bearer_token.rs +0 -0
  53. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/src/capabilities.rs +0 -0
  54. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/src/email_context.rs +0 -0
  55. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/src/german.rs +0 -0
  56. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/src/npi.rs +0 -0
  57. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/src/private_key.rs +0 -0
  58. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/src/scan_selection_tests.rs +0 -0
  59. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/src/selection_tests.rs +0 -0
  60. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/src/us_routing_number.rs +0 -0
  61. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/tests/api_key.rs +0 -0
  62. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/tests/bearer_token.rs +0 -0
  63. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/tests/capabilities.rs +0 -0
  64. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/tests/credential_overlaps.rs +0 -0
  65. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/tests/credential_uri.rs +0 -0
  66. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/tests/email_context.rs +0 -0
  67. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/tests/german.rs +0 -0
  68. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/tests/jwt.rs +0 -0
  69. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/tests/npi.rs +0 -0
  70. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/tests/private_key.rs +0 -0
  71. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/tests/support/synthetic_fixtures.rs +0 -0
  72. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/tests/us_routing_number.rs +0 -0
  73. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/tests/uuid.rs +0 -0
  74. {datafog_core-0.4.4 → datafog_core-0.4.5b2}/python/datafog_core/py.typed +0 -0
@@ -80,7 +80,7 @@ checksum = "914a755b7c2d4af2bdcff7ce1739e2db9a1b81a9b07123d8015786ae03c0980d"
80
80
 
81
81
  [[package]]
82
82
  name = "datafog-core"
83
- version = "0.4.4"
83
+ version = "0.4.5-beta.2"
84
84
  dependencies = [
85
85
  "base64",
86
86
  "futures",
@@ -94,17 +94,18 @@ dependencies = [
94
94
 
95
95
  [[package]]
96
96
  name = "datafog-core-python"
97
- version = "0.4.4"
97
+ version = "0.4.5-beta.2"
98
98
  dependencies = [
99
99
  "datafog-core",
100
100
  "pyo3",
101
101
  "pyo3-async-runtimes",
102
+ "serde",
102
103
  "serde_json",
103
104
  ]
104
105
 
105
106
  [[package]]
106
107
  name = "datafog-node"
107
- version = "0.4.4"
108
+ version = "0.4.5-beta.2"
108
109
  dependencies = [
109
110
  "datafog-core",
110
111
  "napi",
@@ -115,7 +116,7 @@ dependencies = [
115
116
 
116
117
  [[package]]
117
118
  name = "datafog-wasm"
118
- version = "0.4.4"
119
+ version = "0.4.5-beta.2"
119
120
  dependencies = [
120
121
  "datafog-core",
121
122
  "serde",
@@ -0,0 +1,246 @@
1
+ Metadata-Version: 2.4
2
+ Name: datafog-core
3
+ Version: 0.4.5b2
4
+ Classifier: Development Status :: 3 - Alpha
5
+ Classifier: License :: OSI Approved :: MIT License
6
+ Classifier: Programming Language :: Python :: 3
7
+ Classifier: Programming Language :: Python :: 3 :: Only
8
+ Classifier: Programming Language :: Python :: 3.10
9
+ Classifier: Programming Language :: Python :: 3.11
10
+ Classifier: Programming Language :: Python :: 3.12
11
+ Classifier: Programming Language :: Python :: 3.13
12
+ Classifier: Programming Language :: Python :: 3.14
13
+ Classifier: Programming Language :: Rust
14
+ Requires-Dist: gliner2[local]==2.1.0 ; extra == 'gliner2'
15
+ Requires-Dist: transformers==5.8.0 ; (platform_machine != 'x86_64' and extra == 'gliner2') or (sys_platform != 'darwin' and extra == 'gliner2')
16
+ Requires-Dist: torch==2.12.0 ; (platform_machine != 'x86_64' and extra == 'gliner2') or (sys_platform != 'darwin' and extra == 'gliner2')
17
+ Requires-Dist: peft==0.21.2 ; (platform_machine != 'x86_64' and extra == 'gliner2') or (sys_platform != 'darwin' and extra == 'gliner2')
18
+ Requires-Dist: transformers==4.57.6 ; platform_machine == 'x86_64' and sys_platform == 'darwin' and extra == 'gliner2'
19
+ Requires-Dist: torch==2.2.2 ; platform_machine == 'x86_64' and sys_platform == 'darwin' and extra == 'gliner2'
20
+ Requires-Dist: protobuf==6.33.6 ; platform_machine == 'x86_64' and sys_platform == 'darwin' and extra == 'gliner2'
21
+ Requires-Dist: numpy==1.26.4 ; platform_machine == 'x86_64' and sys_platform == 'darwin' and extra == 'gliner2'
22
+ Requires-Dist: peft==0.18.1 ; platform_machine == 'x86_64' and sys_platform == 'darwin' and extra == 'gliner2'
23
+ Provides-Extra: gliner2
24
+ Summary: Fast structured PII detection implemented in Rust
25
+ Keywords: pii,privacy,detection,rust
26
+ Author: DataFog
27
+ License-Expression: MIT
28
+ Requires-Python: >=3.10
29
+ Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
30
+ Project-URL: Homepage, https://github.com/DataFog/datafog-core
31
+ Project-URL: Issues, https://github.com/DataFog/datafog-core/issues
32
+ Project-URL: Repository, https://github.com/DataFog/datafog-core
33
+
34
+ <p align="center">
35
+ <a href="https://datafog.ai"><img src="docs/favicon.svg" width="72" height="72" alt="DataFog"></a>
36
+ </p>
37
+
38
+ <h1 align="center">DataFog Core</h1>
39
+
40
+ <p align="center"><strong>Find and transform sensitive data in your application.</strong></p>
41
+
42
+ <p align="center">
43
+ <a href="https://pypi.org/project/datafog-core/"><img src="https://img.shields.io/pypi/v/datafog-core?style=flat-square&amp;color=E8A84C" alt="PyPI version"></a>
44
+ <a href="https://www.npmjs.com/package/@datafog/node"><img src="https://img.shields.io/npm/v/%40datafog%2Fnode?style=flat-square&amp;color=E8A84C" alt="npm version"></a>
45
+ <a href="https://crates.io/crates/datafog-core"><img src="https://img.shields.io/crates/v/datafog-core?style=flat-square&amp;color=E8A84C" alt="crates.io version"></a>
46
+ <a href="https://github.com/DataFog/datafog-core/actions/workflows/rust-quality.yml"><img src="https://github.com/DataFog/datafog-core/actions/workflows/rust-quality.yml/badge.svg?branch=main" alt="Rust CI status"></a>
47
+ <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-E8A84C?style=flat-square" alt="MIT license"></a>
48
+ </p>
49
+
50
+ <p align="center">
51
+ <a href="#quickstart">Quickstart</a> ·
52
+ <a href="#detection-coverage">Detection</a> ·
53
+ <a href="#transformations">Transformations</a> ·
54
+ <a href="#local-models-beta">Local models</a> ·
55
+ <a href="#documentation-and-development">Documentation</a>
56
+ </p>
57
+
58
+ DataFog Core is a Rust library with Python, Node.js, and browser WebAssembly bindings. Scan text or JSON for personal data and credentials, then redact, mask, remove, pseudonymize, or tokenize matched values. Findings use a consistent format across the bindings.
59
+
60
+ Rule-based scanning runs locally without model weights or downloads. Optional local model sessions add DataFog and GLiNER2 support in Rust, Python, and Node.js.
61
+
62
+ **Stable:** [0.4.4](https://github.com/DataFog/datafog-core/releases/tag/v0.4.4) · **Model beta:** [0.4.5-beta.1](https://github.com/DataFog/datafog-core/releases/tag/v0.4.5-beta.1)
63
+
64
+ ## Quickstart
65
+
66
+ Choose the package for your application:
67
+
68
+ | SDK | Install stable | Requirements |
69
+ | --- | --- | --- |
70
+ | [Python](https://pypi.org/project/datafog-core/) | `python -m pip install datafog-core` | Python 3.10+ |
71
+ | [Node.js](https://www.npmjs.com/package/@datafog/node) | `npm install @datafog/node` | Node.js 24.x |
72
+ | [Rust](https://crates.io/crates/datafog-core) | `cargo add datafog-core` | Rust 1.88+ |
73
+ | [Browser / WASM](https://www.npmjs.com/package/@datafog/wasm) | `npm install @datafog/wasm` | Browser with WebAssembly support |
74
+
75
+ ### Python
76
+
77
+ ```python
78
+ from datafog_core import scan, scan_and_transform
79
+
80
+ findings = scan("Email jane@example.com")
81
+ print(findings[0].entity_type) # EMAIL
82
+ print(findings[0].matched_text) # jane@example.com
83
+
84
+ result = scan_and_transform(
85
+ "Email jane@example.com",
86
+ {"transform": {"default": {"strategy": "redact"}}},
87
+ )
88
+ print(result.text) # Email [EMAIL]
89
+ ```
90
+
91
+ <details>
92
+ <summary><strong>Node.js example</strong></summary>
93
+
94
+ ```js
95
+ import { scan, scanAndTransform } from "@datafog/node";
96
+
97
+ const findings = scan("Email jane@example.com");
98
+ console.log(findings[0].entityType); // EMAIL
99
+ console.log(findings[0].matchedText); // jane@example.com
100
+
101
+ const result = scanAndTransform("Email jane@example.com", {
102
+ transform: { default: { strategy: "redact" } },
103
+ });
104
+ console.log(result.text); // Email [EMAIL]
105
+ ```
106
+
107
+ </details>
108
+
109
+ <details>
110
+ <summary><strong>Rust example</strong></summary>
111
+
112
+ ```rust
113
+ use datafog_core::{
114
+ scan, scan_and_transform, PrivacyError, ScanAndTransformConfig,
115
+ TransformationConfig, TransformationStrategy,
116
+ };
117
+
118
+ fn main() -> Result<(), PrivacyError> {
119
+ let findings = scan("Email jane@example.com");
120
+ println!("{}", findings[0].entity_type); // EMAIL
121
+ println!("{}", findings[0].matched_text); // jane@example.com
122
+
123
+ let result = scan_and_transform(
124
+ "Email jane@example.com",
125
+ &ScanAndTransformConfig::new(TransformationConfig::new(
126
+ TransformationStrategy::Redact,
127
+ )),
128
+ )?;
129
+ println!("{}", result.text); // Email [EMAIL]
130
+ Ok(())
131
+ }
132
+ ```
133
+
134
+ </details>
135
+
136
+ <details>
137
+ <summary><strong>Browser / WASM example</strong></summary>
138
+
139
+ ```js
140
+ import { init, scan, scanAndTransform } from "@datafog/wasm";
141
+
142
+ await init();
143
+ console.log(scan("Email jane@example.com"));
144
+
145
+ const result = scanAndTransform("Email jane@example.com", {
146
+ transform: { default: { strategy: "redact" } },
147
+ });
148
+ console.log(result.text); // Email [EMAIL]
149
+ ```
150
+
151
+ </details>
152
+
153
+ Python and Node.js packages include prebuilt native binaries for Linux x64 and ARM64 (GNU), macOS Intel and Apple Silicon, and Windows x64 (MSVC).
154
+
155
+ ## Detection coverage
156
+
157
+ | Coverage | Entity types | Activation |
158
+ | --- | --- | --- |
159
+ | Personal and financial data | `EMAIL`, `PHONE`, `SSN`, `CREDIT_CARD`, `IP_ADDRESS`, `DATE`, `ZIP_CODE` | On by default |
160
+ | Credentials | [`API_KEY`](docs/reference/api-keys.mdx), [`BEARER_TOKEN`](docs/reference/bearer-token.mdx), [`JWT`](docs/reference/jwt.mdx), [`PRIVATE_KEY`](docs/reference/private-keys.mdx), [`CREDENTIAL_URI`](docs/reference/credential-uri.mdx) | On by default |
161
+ | Labeled US identifiers | [`US_ROUTING_NUMBER`](docs/reference/us-routing-number.mdx), [`NPI`](docs/reference/npi.mdx) | On by default; requires a supported text label |
162
+ | German identifiers | IBAN, VAT ID, tax ID, social security number, postal code, passport number, residence permit number | Explicit [German locale](docs/reference/german-entities.mdx) |
163
+ | UUIDs | [`UUID`](docs/reference/uuid.mdx) | Explicit `detect_uuid` setting |
164
+ | Names in JSON fields | `PERSON` | [Structured scans](docs/guides/person-discovery.mdx), using name-field aliases or explicit JSON Pointer mappings |
165
+
166
+ Use [structured scans](docs/guides/person-discovery.mdx) to find names by JSON field, or [local models](#local-models-beta) to detect names and street addresses in prose.
167
+
168
+ Each finding includes its entity type, matched text, byte and code-point ranges, optional confidence, and detector name/version. Ranges are zero-based and end-exclusive. Node.js and WASM also provide UTF-16 ranges for JavaScript `slice`. Rule-based findings have no confidence score. [Findings and ranges →](docs/concepts/findings-and-ranges.mdx)
169
+
170
+ For scanning files from AI agents, use [DataFog MCP](https://github.com/DataFog/datafog-mcp).
171
+
172
+ <details>
173
+ <summary><strong>Detection settings</strong></summary>
174
+
175
+ - **Select checks:** `scan(text, {"entities": ["EMAIL", "SSN"]})` in Python runs only the selected text detectors. Omit `entities` to use all enabled detectors. Selections must be nonempty, unique, exact entity names. Selecting a German type or UUID does not activate it; set `locale` or `detect_uuid` too.
176
+ - **German locale:** `{"locale": "de"}` enables the seven German detectors. These use format/context rules; IBAN checksums and account existence are not verified. See the [German reference](docs/reference/german-entities.mdx) for detector rules.
177
+ - **ENV and SQL:** choose `format: "env"` or `format: "sql"` to handle email boundaries in assignments and quoted strings. [Source-context rules →](docs/guides/email-boundaries.mdx)
178
+ - **Phone numbers:** numbers without `+` use North American checks: ten digits, optionally preceded by `1`, with area and exchange codes starting with `2`–`9`. Numbers starting with `+` use a permissive 7–15 digit check, including shortened examples such as `+1-555-1002`. Country codes and assigned numbers are not validated; numeric identifiers can still match.
179
+ - **Decimal numbers and CSV:** contiguous card digits after a digit and `.` or `,` are suppressed, so `3.4111111111111111` and `3,4111111111111111` do not produce card findings. Cards containing spaces or hyphens still undergo normal checks. Parse CSV/TSV into cells before scanning so delimiters and adjacent fields do not affect matching.
180
+
181
+ Use [`capabilities()`](docs/reference/capabilities.mdx) in Rust or Python to discover supported entities and their activation rules.
182
+
183
+ </details>
184
+
185
+ ## Transformations
186
+
187
+ | Strategy | Result | Application provider | Browser / WASM |
188
+ | --- | --- | --- | --- |
189
+ | `redact` | Replace with a label such as `[EMAIL]` | None | Supported |
190
+ | `mask` | Replace characters, optionally revealing the first or last characters | None | Supported |
191
+ | `remove` | Delete the matched span | None | Supported |
192
+ | [`pseudonymize`](docs/guides/pseudonymization.mdx) | Create a stable keyed HMAC-SHA-256 pseudonym | Key provider | Unsupported |
193
+ | [`tokenize`](docs/guides/tokenization-and-restoration.mdx) | Issue an opaque token that can be restored under the same scope | Token provider | Unsupported |
194
+
195
+ Use `transform` with existing findings, or `scan_and_transform` / `scanAndTransform` to scan and transform together. Transformation records include source/output ranges and replacement metadata, without the original matched text.
196
+
197
+ Keep scan settings under `scan` and transformation policy under `transform`. A default strategy is required; entity selection, per-type overrides, and allowlists are optional. [Configuration guide →](docs/guides/configuration.mdx) · [Strategy details →](docs/concepts/privacy-transformations.mdx)
198
+
199
+ ## Local models (beta)
200
+
201
+ [0.4.5-beta.1](https://github.com/DataFog/datafog-core/releases/tag/v0.4.5-beta.1) adds local sessions for the DataFog PII model and GLiNER2 in Rust, Python, and Node.js on all five native platforms.
202
+
203
+ Install the beta for your runtime:
204
+
205
+ ```bash
206
+ python -m pip install 'datafog-core==0.4.5b1'
207
+ npm install @datafog/node@beta
208
+ cargo add datafog-core@0.4.5-beta.1 --features models
209
+ ```
210
+
211
+ For GLiNER2, install its optional dependencies in the Python environment used by the runner:
212
+
213
+ ```bash
214
+ python -m pip install 'datafog-core[gliner2]==0.4.5b1'
215
+ ```
216
+
217
+ The GLiNER2 runner ships in the Python package and also serves Node.js and Rust callers. Download and verify model files separately, then use `ModelSession.open`, text `scan`, and `close`. Reuse sessions across calls. Both backends return consistent results and errors, with cancellation and cleanup support.
218
+
219
+ [DataFog setup and session API →](docs/model-sessions.md) · [GLiNER2 setup →](docs/gliner2-model.md)
220
+
221
+ ## Documentation and development
222
+
223
+ - [Installation and runtime requirements](docs/get-started/installation.mdx)
224
+ - [Python](docs/reference/python.mdx) · [Node.js](docs/reference/node.mdx) · [Rust](docs/reference/rust.mdx) · [Browser / WASM](docs/reference/browser-wasm.mdx) API references
225
+ - [Structured JSON scans and name-field discovery](docs/guides/person-discovery.mdx)
226
+ - [Configuration and allowlists](docs/guides/configuration.mdx)
227
+ - [Errors](docs/reference/errors.mdx) and [0.4.x compatibility](docs/reference/compatibility.mdx)
228
+ - [Build, test, and contribute](docs/development.mdx)
229
+ - [Release notes](https://github.com/DataFog/datafog-core/releases)
230
+
231
+ For existing `datafog` Python applications, follow the [migration guide](docs/guides/migrating-from-datafog-python.mdx) for changes to imports, results, and transformations.
232
+
233
+ For Rust development, run:
234
+
235
+ ```bash
236
+ cargo fmt --all --check
237
+ cargo clippy --workspace --all-targets --all-features -- -D warnings
238
+ cargo test --workspace --all-features
239
+ ```
240
+
241
+ See the [development guide](docs/development.mdx) for the repository layout and Python, Node.js, and WASM package checks.
242
+
243
+ ## License
244
+
245
+ [MIT](LICENSE). Built by [DataFog](https://datafog.ai).
246
+
@@ -0,0 +1,212 @@
1
+ <p align="center">
2
+ <a href="https://datafog.ai"><img src="docs/favicon.svg" width="72" height="72" alt="DataFog"></a>
3
+ </p>
4
+
5
+ <h1 align="center">DataFog Core</h1>
6
+
7
+ <p align="center"><strong>Find and transform sensitive data in your application.</strong></p>
8
+
9
+ <p align="center">
10
+ <a href="https://pypi.org/project/datafog-core/"><img src="https://img.shields.io/pypi/v/datafog-core?style=flat-square&amp;color=E8A84C" alt="PyPI version"></a>
11
+ <a href="https://www.npmjs.com/package/@datafog/node"><img src="https://img.shields.io/npm/v/%40datafog%2Fnode?style=flat-square&amp;color=E8A84C" alt="npm version"></a>
12
+ <a href="https://crates.io/crates/datafog-core"><img src="https://img.shields.io/crates/v/datafog-core?style=flat-square&amp;color=E8A84C" alt="crates.io version"></a>
13
+ <a href="https://github.com/DataFog/datafog-core/actions/workflows/rust-quality.yml"><img src="https://github.com/DataFog/datafog-core/actions/workflows/rust-quality.yml/badge.svg?branch=main" alt="Rust CI status"></a>
14
+ <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-E8A84C?style=flat-square" alt="MIT license"></a>
15
+ </p>
16
+
17
+ <p align="center">
18
+ <a href="#quickstart">Quickstart</a> ·
19
+ <a href="#detection-coverage">Detection</a> ·
20
+ <a href="#transformations">Transformations</a> ·
21
+ <a href="#local-models-beta">Local models</a> ·
22
+ <a href="#documentation-and-development">Documentation</a>
23
+ </p>
24
+
25
+ DataFog Core is a Rust library with Python, Node.js, and browser WebAssembly bindings. Scan text or JSON for personal data and credentials, then redact, mask, remove, pseudonymize, or tokenize matched values. Findings use a consistent format across the bindings.
26
+
27
+ Rule-based scanning runs locally without model weights or downloads. Optional local model sessions add DataFog and GLiNER2 support in Rust, Python, and Node.js.
28
+
29
+ **Stable:** [0.4.4](https://github.com/DataFog/datafog-core/releases/tag/v0.4.4) · **Model beta:** [0.4.5-beta.1](https://github.com/DataFog/datafog-core/releases/tag/v0.4.5-beta.1)
30
+
31
+ ## Quickstart
32
+
33
+ Choose the package for your application:
34
+
35
+ | SDK | Install stable | Requirements |
36
+ | --- | --- | --- |
37
+ | [Python](https://pypi.org/project/datafog-core/) | `python -m pip install datafog-core` | Python 3.10+ |
38
+ | [Node.js](https://www.npmjs.com/package/@datafog/node) | `npm install @datafog/node` | Node.js 24.x |
39
+ | [Rust](https://crates.io/crates/datafog-core) | `cargo add datafog-core` | Rust 1.88+ |
40
+ | [Browser / WASM](https://www.npmjs.com/package/@datafog/wasm) | `npm install @datafog/wasm` | Browser with WebAssembly support |
41
+
42
+ ### Python
43
+
44
+ ```python
45
+ from datafog_core import scan, scan_and_transform
46
+
47
+ findings = scan("Email jane@example.com")
48
+ print(findings[0].entity_type) # EMAIL
49
+ print(findings[0].matched_text) # jane@example.com
50
+
51
+ result = scan_and_transform(
52
+ "Email jane@example.com",
53
+ {"transform": {"default": {"strategy": "redact"}}},
54
+ )
55
+ print(result.text) # Email [EMAIL]
56
+ ```
57
+
58
+ <details>
59
+ <summary><strong>Node.js example</strong></summary>
60
+
61
+ ```js
62
+ import { scan, scanAndTransform } from "@datafog/node";
63
+
64
+ const findings = scan("Email jane@example.com");
65
+ console.log(findings[0].entityType); // EMAIL
66
+ console.log(findings[0].matchedText); // jane@example.com
67
+
68
+ const result = scanAndTransform("Email jane@example.com", {
69
+ transform: { default: { strategy: "redact" } },
70
+ });
71
+ console.log(result.text); // Email [EMAIL]
72
+ ```
73
+
74
+ </details>
75
+
76
+ <details>
77
+ <summary><strong>Rust example</strong></summary>
78
+
79
+ ```rust
80
+ use datafog_core::{
81
+ scan, scan_and_transform, PrivacyError, ScanAndTransformConfig,
82
+ TransformationConfig, TransformationStrategy,
83
+ };
84
+
85
+ fn main() -> Result<(), PrivacyError> {
86
+ let findings = scan("Email jane@example.com");
87
+ println!("{}", findings[0].entity_type); // EMAIL
88
+ println!("{}", findings[0].matched_text); // jane@example.com
89
+
90
+ let result = scan_and_transform(
91
+ "Email jane@example.com",
92
+ &ScanAndTransformConfig::new(TransformationConfig::new(
93
+ TransformationStrategy::Redact,
94
+ )),
95
+ )?;
96
+ println!("{}", result.text); // Email [EMAIL]
97
+ Ok(())
98
+ }
99
+ ```
100
+
101
+ </details>
102
+
103
+ <details>
104
+ <summary><strong>Browser / WASM example</strong></summary>
105
+
106
+ ```js
107
+ import { init, scan, scanAndTransform } from "@datafog/wasm";
108
+
109
+ await init();
110
+ console.log(scan("Email jane@example.com"));
111
+
112
+ const result = scanAndTransform("Email jane@example.com", {
113
+ transform: { default: { strategy: "redact" } },
114
+ });
115
+ console.log(result.text); // Email [EMAIL]
116
+ ```
117
+
118
+ </details>
119
+
120
+ Python and Node.js packages include prebuilt native binaries for Linux x64 and ARM64 (GNU), macOS Intel and Apple Silicon, and Windows x64 (MSVC).
121
+
122
+ ## Detection coverage
123
+
124
+ | Coverage | Entity types | Activation |
125
+ | --- | --- | --- |
126
+ | Personal and financial data | `EMAIL`, `PHONE`, `SSN`, `CREDIT_CARD`, `IP_ADDRESS`, `DATE`, `ZIP_CODE` | On by default |
127
+ | Credentials | [`API_KEY`](docs/reference/api-keys.mdx), [`BEARER_TOKEN`](docs/reference/bearer-token.mdx), [`JWT`](docs/reference/jwt.mdx), [`PRIVATE_KEY`](docs/reference/private-keys.mdx), [`CREDENTIAL_URI`](docs/reference/credential-uri.mdx) | On by default |
128
+ | Labeled US identifiers | [`US_ROUTING_NUMBER`](docs/reference/us-routing-number.mdx), [`NPI`](docs/reference/npi.mdx) | On by default; requires a supported text label |
129
+ | German identifiers | IBAN, VAT ID, tax ID, social security number, postal code, passport number, residence permit number | Explicit [German locale](docs/reference/german-entities.mdx) |
130
+ | UUIDs | [`UUID`](docs/reference/uuid.mdx) | Explicit `detect_uuid` setting |
131
+ | Names in JSON fields | `PERSON` | [Structured scans](docs/guides/person-discovery.mdx), using name-field aliases or explicit JSON Pointer mappings |
132
+
133
+ Use [structured scans](docs/guides/person-discovery.mdx) to find names by JSON field, or [local models](#local-models-beta) to detect names and street addresses in prose.
134
+
135
+ Each finding includes its entity type, matched text, byte and code-point ranges, optional confidence, and detector name/version. Ranges are zero-based and end-exclusive. Node.js and WASM also provide UTF-16 ranges for JavaScript `slice`. Rule-based findings have no confidence score. [Findings and ranges →](docs/concepts/findings-and-ranges.mdx)
136
+
137
+ For scanning files from AI agents, use [DataFog MCP](https://github.com/DataFog/datafog-mcp).
138
+
139
+ <details>
140
+ <summary><strong>Detection settings</strong></summary>
141
+
142
+ - **Select checks:** `scan(text, {"entities": ["EMAIL", "SSN"]})` in Python runs only the selected text detectors. Omit `entities` to use all enabled detectors. Selections must be nonempty, unique, exact entity names. Selecting a German type or UUID does not activate it; set `locale` or `detect_uuid` too.
143
+ - **German locale:** `{"locale": "de"}` enables the seven German detectors. These use format/context rules; IBAN checksums and account existence are not verified. See the [German reference](docs/reference/german-entities.mdx) for detector rules.
144
+ - **ENV and SQL:** choose `format: "env"` or `format: "sql"` to handle email boundaries in assignments and quoted strings. [Source-context rules →](docs/guides/email-boundaries.mdx)
145
+ - **Phone numbers:** numbers without `+` use North American checks: ten digits, optionally preceded by `1`, with area and exchange codes starting with `2`–`9`. Numbers starting with `+` use a permissive 7–15 digit check, including shortened examples such as `+1-555-1002`. Country codes and assigned numbers are not validated; numeric identifiers can still match.
146
+ - **Decimal numbers and CSV:** contiguous card digits after a digit and `.` or `,` are suppressed, so `3.4111111111111111` and `3,4111111111111111` do not produce card findings. Cards containing spaces or hyphens still undergo normal checks. Parse CSV/TSV into cells before scanning so delimiters and adjacent fields do not affect matching.
147
+
148
+ Use [`capabilities()`](docs/reference/capabilities.mdx) in Rust or Python to discover supported entities and their activation rules.
149
+
150
+ </details>
151
+
152
+ ## Transformations
153
+
154
+ | Strategy | Result | Application provider | Browser / WASM |
155
+ | --- | --- | --- | --- |
156
+ | `redact` | Replace with a label such as `[EMAIL]` | None | Supported |
157
+ | `mask` | Replace characters, optionally revealing the first or last characters | None | Supported |
158
+ | `remove` | Delete the matched span | None | Supported |
159
+ | [`pseudonymize`](docs/guides/pseudonymization.mdx) | Create a stable keyed HMAC-SHA-256 pseudonym | Key provider | Unsupported |
160
+ | [`tokenize`](docs/guides/tokenization-and-restoration.mdx) | Issue an opaque token that can be restored under the same scope | Token provider | Unsupported |
161
+
162
+ Use `transform` with existing findings, or `scan_and_transform` / `scanAndTransform` to scan and transform together. Transformation records include source/output ranges and replacement metadata, without the original matched text.
163
+
164
+ Keep scan settings under `scan` and transformation policy under `transform`. A default strategy is required; entity selection, per-type overrides, and allowlists are optional. [Configuration guide →](docs/guides/configuration.mdx) · [Strategy details →](docs/concepts/privacy-transformations.mdx)
165
+
166
+ ## Local models (beta)
167
+
168
+ [0.4.5-beta.1](https://github.com/DataFog/datafog-core/releases/tag/v0.4.5-beta.1) adds local sessions for the DataFog PII model and GLiNER2 in Rust, Python, and Node.js on all five native platforms.
169
+
170
+ Install the beta for your runtime:
171
+
172
+ ```bash
173
+ python -m pip install 'datafog-core==0.4.5b1'
174
+ npm install @datafog/node@beta
175
+ cargo add datafog-core@0.4.5-beta.1 --features models
176
+ ```
177
+
178
+ For GLiNER2, install its optional dependencies in the Python environment used by the runner:
179
+
180
+ ```bash
181
+ python -m pip install 'datafog-core[gliner2]==0.4.5b1'
182
+ ```
183
+
184
+ The GLiNER2 runner ships in the Python package and also serves Node.js and Rust callers. Download and verify model files separately, then use `ModelSession.open`, text `scan`, and `close`. Reuse sessions across calls. Both backends return consistent results and errors, with cancellation and cleanup support.
185
+
186
+ [DataFog setup and session API →](docs/model-sessions.md) · [GLiNER2 setup →](docs/gliner2-model.md)
187
+
188
+ ## Documentation and development
189
+
190
+ - [Installation and runtime requirements](docs/get-started/installation.mdx)
191
+ - [Python](docs/reference/python.mdx) · [Node.js](docs/reference/node.mdx) · [Rust](docs/reference/rust.mdx) · [Browser / WASM](docs/reference/browser-wasm.mdx) API references
192
+ - [Structured JSON scans and name-field discovery](docs/guides/person-discovery.mdx)
193
+ - [Configuration and allowlists](docs/guides/configuration.mdx)
194
+ - [Errors](docs/reference/errors.mdx) and [0.4.x compatibility](docs/reference/compatibility.mdx)
195
+ - [Build, test, and contribute](docs/development.mdx)
196
+ - [Release notes](https://github.com/DataFog/datafog-core/releases)
197
+
198
+ For existing `datafog` Python applications, follow the [migration guide](docs/guides/migrating-from-datafog-python.mdx) for changes to imports, results, and transformations.
199
+
200
+ For Rust development, run:
201
+
202
+ ```bash
203
+ cargo fmt --all --check
204
+ cargo clippy --workspace --all-targets --all-features -- -D warnings
205
+ cargo test --workspace --all-features
206
+ ```
207
+
208
+ See the [development guide](docs/development.mdx) for the repository layout and Python, Node.js, and WASM package checks.
209
+
210
+ ## License
211
+
212
+ [MIT](LICENSE). Built by [DataFog](https://datafog.ai).
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "datafog-core-python"
3
- version = "0.4.4"
3
+ version = "0.4.5-beta.2"
4
4
  edition = "2024"
5
5
  rust-version = "1.88"
6
6
  description = "Python bindings for datafog-core"
@@ -12,7 +12,8 @@ name = "datafog_core"
12
12
  crate-type = ["cdylib"]
13
13
 
14
14
  [dependencies]
15
- datafog-core = { path = "../../crates/core" }
15
+ datafog-core = { version = "0.4.5-beta.2", path = "../../crates/core", features = ["models"] }
16
16
  pyo3 = { version = "0.29", features = ["abi3-py310"] }
17
17
  pyo3-async-runtimes = { version = "0.29", features = ["tokio-runtime"] }
18
18
  serde_json = "1"
19
+ serde = "1"
@@ -1,4 +1,5 @@
1
1
  use ::datafog_core as core;
2
+ mod models;
2
3
  use pyo3::create_exception;
3
4
  use pyo3::exceptions::{PyRuntimeError, PyTypeError, PyValueError};
4
5
  use pyo3::prelude::*;
@@ -974,13 +975,11 @@ fn scan(py: Python<'_>, text: &str, config: Option<&Bound<'_, PyAny>>) -> PyResu
974
975
  } else {
975
976
  core::ScanConfig::default()
976
977
  };
977
- std::panic::catch_unwind(|| {
978
- core::scan_with_config(text, &config)
979
- .into_iter()
980
- .map(Finding::from)
981
- .collect()
982
- })
983
- .map_err(|_| internal_error(py, "unexpected Rust scan failure"))
978
+ // Python strings are immutable, so other threads may run during the scan.
979
+ let findings = py
980
+ .detach(|| std::panic::catch_unwind(|| core::scan_with_config(text, &config)))
981
+ .map_err(|_| internal_error(py, "unexpected Rust scan failure"))?;
982
+ Ok(findings.into_iter().map(Finding::from).collect())
984
983
  }
985
984
 
986
985
  /// Transform explicit findings without scanning implicitly.
@@ -1274,6 +1273,7 @@ fn scan_and_transform_structured(
1274
1273
 
1275
1274
  #[pymodule]
1276
1275
  fn datafog_core(module: &Bound<'_, PyModule>) -> PyResult<()> {
1276
+ models::register(module)?;
1277
1277
  module.add(
1278
1278
  "DataFogConfigurationError",
1279
1279
  module.py().get_type::<DataFogConfigurationError>(),