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.
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/Cargo.lock +5 -4
- datafog_core-0.4.5b2/PKG-INFO +246 -0
- datafog_core-0.4.5b2/README.md +212 -0
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/bindings/python/Cargo.toml +3 -2
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/bindings/python/src/lib.rs +7 -7
- datafog_core-0.4.5b2/bindings/python/src/models.rs +139 -0
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/Cargo.toml +5 -1
- datafog_core-0.4.5b2/crates/core/README.md +212 -0
- datafog_core-0.4.5b2/crates/core/src/api_key.rs +172 -0
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/src/credential_uri.rs +125 -17
- datafog_core-0.4.5b2/crates/core/src/jwt.rs +169 -0
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/src/lib.rs +833 -124
- datafog_core-0.4.5b2/crates/core/src/models/gliner2-lock.json +35 -0
- datafog_core-0.4.5b2/crates/core/src/models/gliner2.rs +352 -0
- datafog_core-0.4.5b2/crates/core/src/models/process.rs +192 -0
- datafog_core-0.4.5b2/crates/core/src/models/tests.rs +336 -0
- datafog_core-0.4.5b2/crates/core/src/models.rs +984 -0
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/src/offsets.rs +17 -3
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/src/structured.rs +49 -34
- datafog_core-0.4.5b2/crates/core/src/uuid.rs +91 -0
- datafog_core-0.4.5b2/crates/core/tests/model_datafog.rs +44 -0
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/pyproject.toml +14 -1
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/python/datafog_core/__init__.py +8 -0
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/python/datafog_core/__init__.pyi +60 -0
- datafog_core-0.4.5b2/python/datafog_core/_gliner2_worker.py +91 -0
- datafog_core-0.4.4/PKG-INFO +0 -382
- datafog_core-0.4.4/README.md +0 -358
- datafog_core-0.4.4/crates/core/README.md +0 -358
- datafog_core-0.4.4/crates/core/src/api_key.rs +0 -66
- datafog_core-0.4.4/crates/core/src/jwt.rs +0 -66
- datafog_core-0.4.4/crates/core/src/uuid.rs +0 -42
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/Cargo.toml +0 -0
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/bindings/python/tests/api_key_conformance.py +0 -0
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/bindings/python/tests/bearer_token_conformance.py +0 -0
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/bindings/python/tests/capabilities_conformance.py +0 -0
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/bindings/python/tests/credential_overlap_conformance.py +0 -0
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/bindings/python/tests/credential_uri_conformance.py +0 -0
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/bindings/python/tests/email_context_conformance.py +0 -0
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/bindings/python/tests/german_conformance.py +0 -0
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/bindings/python/tests/jwt_conformance.py +0 -0
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/bindings/python/tests/npi_conformance.py +0 -0
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/bindings/python/tests/private_key_conformance.py +0 -0
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/bindings/python/tests/requirements-typing.txt +0 -0
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/bindings/python/tests/synthetic_fixtures.py +0 -0
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/bindings/python/tests/test_installed.py +0 -0
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/bindings/python/tests/test_python49_integration.py +0 -0
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/bindings/python/tests/test_typing.py +0 -0
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/bindings/python/tests/us_routing_number_conformance.py +0 -0
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/bindings/python/tests/uuid_conformance.py +0 -0
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/examples/german_benchmark.rs +0 -0
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/examples/scan_benchmark.rs +0 -0
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/src/bearer_token.rs +0 -0
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/src/capabilities.rs +0 -0
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/src/email_context.rs +0 -0
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/src/german.rs +0 -0
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/src/npi.rs +0 -0
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/src/private_key.rs +0 -0
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/src/scan_selection_tests.rs +0 -0
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/src/selection_tests.rs +0 -0
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/src/us_routing_number.rs +0 -0
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/tests/api_key.rs +0 -0
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/tests/bearer_token.rs +0 -0
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/tests/capabilities.rs +0 -0
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/tests/credential_overlaps.rs +0 -0
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/tests/credential_uri.rs +0 -0
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/tests/email_context.rs +0 -0
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/tests/german.rs +0 -0
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/tests/jwt.rs +0 -0
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/tests/npi.rs +0 -0
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/tests/private_key.rs +0 -0
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/tests/support/synthetic_fixtures.rs +0 -0
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/tests/us_routing_number.rs +0 -0
- {datafog_core-0.4.4 → datafog_core-0.4.5b2}/crates/core/tests/uuid.rs +0 -0
- {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.
|
|
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.
|
|
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.
|
|
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.
|
|
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&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&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&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&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&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&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.
|
|
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
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
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>(),
|