piihush 0.1.0__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.
@@ -0,0 +1 @@
1
+ * @aziaya
@@ -0,0 +1 @@
1
+ github: aziaya
@@ -0,0 +1,28 @@
1
+ name: Bug report
2
+ description: Something masks incorrectly, crashes or behaves unexpectedly
3
+ labels: [bug]
4
+ body:
5
+ - type: markdown
6
+ attributes:
7
+ value: "**Use made-up data only.** Never paste real personal data, keys or passwords."
8
+ - type: textarea
9
+ id: example
10
+ attributes:
11
+ label: Example
12
+ description: A short code example using made-up values.
13
+ render: python
14
+ validations:
15
+ required: true
16
+ - type: textarea
17
+ id: expected
18
+ attributes:
19
+ label: Expected and actual result
20
+ validations:
21
+ required: true
22
+ - type: input
23
+ id: versions
24
+ attributes:
25
+ label: Versions
26
+ description: piihush version, Python version and operating system.
27
+ validations:
28
+ required: true
@@ -0,0 +1,5 @@
1
+ blank_issues_enabled: false
2
+ contact_links:
3
+ - name: Report a security vulnerability
4
+ url: https://github.com/aziaya/piihush/security/advisories/new
5
+ about: Report vulnerabilities privately, not in a public issue.
@@ -0,0 +1,15 @@
1
+ name: Feature request
2
+ description: Suggest a new detector or improvement
3
+ labels: [enhancement]
4
+ body:
5
+ - type: textarea
6
+ id: problem
7
+ attributes:
8
+ label: Problem
9
+ description: What are you trying to do? For a new detector, give made-up examples.
10
+ validations:
11
+ required: true
12
+ - type: textarea
13
+ id: proposal
14
+ attributes:
15
+ label: Proposed solution
@@ -0,0 +1,11 @@
1
+ ## What this changes
2
+
3
+ <!-- Describe the change and why it's needed. Link any related issue. -->
4
+
5
+ ## Checklist
6
+
7
+ - [ ] Tests cover the change
8
+ - [ ] `cargo fmt` and `cargo clippy` pass
9
+ - [ ] New detectors are tested on look-alikes that must stay unmasked
10
+ - [ ] `CHANGELOG.md` and the README are updated if behavior changed
11
+ - [ ] All examples and test data are made up, with no real personal data
@@ -0,0 +1,10 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: cargo
4
+ directory: /
5
+ schedule:
6
+ interval: weekly
7
+ - package-ecosystem: github-actions
8
+ directory: /
9
+ schedule:
10
+ interval: weekly
@@ -0,0 +1,105 @@
1
+ {
2
+ "name": "Protect master",
3
+ "target": "branch",
4
+ "enforcement": "active",
5
+ "bypass_actors": [
6
+ {
7
+ "actor_id": 5,
8
+ "actor_type": "RepositoryRole",
9
+ "bypass_mode": "pull_request"
10
+ }
11
+ ],
12
+ "conditions": {
13
+ "ref_name": {
14
+ "include": [
15
+ "~DEFAULT_BRANCH"
16
+ ],
17
+ "exclude": []
18
+ }
19
+ },
20
+ "rules": [
21
+ {
22
+ "type": "deletion"
23
+ },
24
+ {
25
+ "type": "non_fast_forward"
26
+ },
27
+ {
28
+ "type": "required_linear_history"
29
+ },
30
+ {
31
+ "type": "pull_request",
32
+ "parameters": {
33
+ "required_approving_review_count": 1,
34
+ "dismiss_stale_reviews_on_push": true,
35
+ "require_code_owner_review": true,
36
+ "require_last_push_approval": false,
37
+ "required_review_thread_resolution": true,
38
+ "allowed_merge_methods": [
39
+ "squash"
40
+ ]
41
+ }
42
+ },
43
+ {
44
+ "type": "required_status_checks",
45
+ "parameters": {
46
+ "strict_required_status_checks_policy": true,
47
+ "do_not_enforce_on_create": false,
48
+ "required_status_checks": [
49
+ {
50
+ "context": "rust",
51
+ "integration_id": 15368
52
+ },
53
+ {
54
+ "context": "python (ubuntu-latest, 3.11)",
55
+ "integration_id": 15368
56
+ },
57
+ {
58
+ "context": "python (ubuntu-latest, 3.14)",
59
+ "integration_id": 15368
60
+ },
61
+ {
62
+ "context": "python (ubuntu-latest, 3.15)",
63
+ "integration_id": 15368
64
+ },
65
+ {
66
+ "context": "python (ubuntu-24.04-arm, 3.11)",
67
+ "integration_id": 15368
68
+ },
69
+ {
70
+ "context": "python (ubuntu-24.04-arm, 3.14)",
71
+ "integration_id": 15368
72
+ },
73
+ {
74
+ "context": "python (ubuntu-24.04-arm, 3.15)",
75
+ "integration_id": 15368
76
+ },
77
+ {
78
+ "context": "python (macos-latest, 3.11)",
79
+ "integration_id": 15368
80
+ },
81
+ {
82
+ "context": "python (macos-latest, 3.14)",
83
+ "integration_id": 15368
84
+ },
85
+ {
86
+ "context": "python (macos-latest, 3.15)",
87
+ "integration_id": 15368
88
+ },
89
+ {
90
+ "context": "python (windows-latest, 3.11)",
91
+ "integration_id": 15368
92
+ },
93
+ {
94
+ "context": "python (windows-latest, 3.14)",
95
+ "integration_id": 15368
96
+ },
97
+ {
98
+ "context": "python (windows-latest, 3.15)",
99
+ "integration_id": 15368
100
+ }
101
+ ]
102
+ }
103
+ }
104
+ ]
105
+ }
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "Protect release tags",
3
+ "target": "tag",
4
+ "enforcement": "active",
5
+ "bypass_actors": [],
6
+ "conditions": {
7
+ "ref_name": {
8
+ "include": [
9
+ "refs/tags/v*"
10
+ ],
11
+ "exclude": []
12
+ }
13
+ },
14
+ "rules": [
15
+ {
16
+ "type": "deletion"
17
+ },
18
+ {
19
+ "type": "non_fast_forward"
20
+ },
21
+ {
22
+ "type": "update"
23
+ }
24
+ ]
25
+ }
@@ -0,0 +1,33 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [master]
6
+ pull_request:
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ rust:
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
16
+ - run: rustup component add rustfmt clippy
17
+ - run: cargo fmt --check
18
+ - run: cargo clippy --all-targets --features python -- -D warnings
19
+ - run: cargo test
20
+
21
+ python:
22
+ runs-on: ${{ matrix.os }}
23
+ strategy:
24
+ fail-fast: false
25
+ matrix:
26
+ os: [ubuntu-latest, ubuntu-24.04-arm, macos-latest, windows-latest]
27
+ python-version: ["3.11", "3.14", "3.15"]
28
+ steps:
29
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
30
+ - uses: astral-sh/setup-uv@68559e99cc807c1eb7e9238fd43a15bba460eec2 # v10.3.3
31
+ with:
32
+ python-version: ${{ matrix.python-version }}
33
+ - run: uv run --group dev pytest
@@ -0,0 +1,83 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ tags: ["v*"]
6
+
7
+ permissions:
8
+ contents: read
9
+
10
+ jobs:
11
+ linux:
12
+ runs-on: ${{ matrix.runner }}
13
+ strategy:
14
+ matrix:
15
+ include:
16
+ - { runner: ubuntu-latest, target: x86_64, manylinux: "2_28" }
17
+ - { runner: ubuntu-24.04-arm, target: aarch64, manylinux: "2_28" }
18
+ - { runner: ubuntu-latest, target: x86_64, manylinux: musllinux_1_2 }
19
+ - { runner: ubuntu-24.04-arm, target: aarch64, manylinux: musllinux_1_2 }
20
+ steps:
21
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
22
+ - uses: PyO3/maturin-action@e83996d129638aa358a18fbd1dfb82f0b0fb5d3b # v1.51.0
23
+ with:
24
+ target: ${{ matrix.target }}
25
+ manylinux: ${{ matrix.manylinux }}
26
+ args: --release --out dist
27
+ - uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
28
+ with:
29
+ name: wheel-linux-${{ matrix.target }}-${{ matrix.manylinux }}
30
+ path: dist
31
+
32
+ macos-windows:
33
+ runs-on: ${{ matrix.runner }}
34
+ strategy:
35
+ matrix:
36
+ include:
37
+ - { runner: macos-latest, target: aarch64-apple-darwin }
38
+ - { runner: macos-latest, target: x86_64-apple-darwin }
39
+ - { runner: windows-latest, target: x86_64-pc-windows-msvc }
40
+ - { runner: windows-11-arm, target: aarch64-pc-windows-msvc }
41
+ steps:
42
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
43
+ - uses: actions/setup-python@6d4fd22b20465ccc0f7354476588e8df7c9ca0e0 # v7.1.0
44
+ with:
45
+ python-version: "3.13"
46
+ - uses: PyO3/maturin-action@e83996d129638aa358a18fbd1dfb82f0b0fb5d3b # v1.51.0
47
+ with:
48
+ target: ${{ matrix.target }}
49
+ args: --release --out dist
50
+ - uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
51
+ with:
52
+ name: wheel-${{ matrix.target }}
53
+ path: dist
54
+
55
+ sdist:
56
+ runs-on: ubuntu-latest
57
+ steps:
58
+ - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
59
+ - uses: PyO3/maturin-action@e83996d129638aa358a18fbd1dfb82f0b0fb5d3b # v1.51.0
60
+ with:
61
+ command: sdist
62
+ args: --out dist
63
+ - uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
64
+ with:
65
+ name: sdist
66
+ path: dist
67
+
68
+ publish:
69
+ needs: [linux, macos-windows, sdist]
70
+ runs-on: ubuntu-latest
71
+ environment: pypi
72
+ permissions:
73
+ id-token: write
74
+ attestations: write
75
+ steps:
76
+ - uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
77
+ with:
78
+ path: dist
79
+ merge-multiple: true
80
+ - uses: actions/attest-build-provenance@4d101475d8b20a2381f78447822ac1eab6504dd8 # v4.2.2
81
+ with:
82
+ subject-path: dist/*
83
+ - uses: pypa/gh-action-pypi-publish@7245906fb61fa33a13554f9d5fb856fe61758086 # v1.14.3
@@ -0,0 +1,11 @@
1
+ /target
2
+ .venv/
3
+ __pycache__/
4
+ *.py[cod]
5
+ *.so
6
+ *.dylib
7
+ *.pyd
8
+ .pytest_cache/
9
+ .hypothesis/
10
+ dist/
11
+ benches/data/
@@ -0,0 +1,10 @@
1
+ # Changelog
2
+
3
+ This project follows [Semantic Versioning](https://semver.org/).
4
+
5
+ ## 0.1.0 - Unreleased
6
+
7
+ Initial release: detectors for email, phone, SSN, credit card, IBAN, IP address,
8
+ API key, JWT, private key, ID number, password, date of birth, address, person and
9
+ username, with custom patterns, deny and allow lists, and parallel batch masking.
10
+ Optional model-based name and place detection through `piihush[ner]`.
@@ -0,0 +1,43 @@
1
+ # Contributing
2
+
3
+ ## Workflow
4
+
5
+ `master` is protected, so every change goes through a pull request, including the
6
+ maintainer's.
7
+
8
+ 1. Fork the repository and create a branch from `master`.
9
+ 2. Make your change, with tests.
10
+ 3. Open a pull request and fill in the template.
11
+ 4. Once CI passes and a code owner approves, the pull request is squash-merged.
12
+
13
+ ## Setup
14
+
15
+ You need Rust (stable) and [uv](https://docs.astral.sh/uv/).
16
+
17
+ ```sh
18
+ cargo test # Rust tests, no Python needed
19
+ uv run --group dev pytest # builds the extension, then runs the Python tests
20
+ python benches/bench.py # speed, from an environment with a release build
21
+ python benches/accuracy.py # accuracy, see the file for setup
22
+ ```
23
+
24
+ Before opening a pull request, run `cargo fmt` and
25
+ `cargo clippy --all-targets --features python -- -D warnings`.
26
+
27
+ ## Adding a detector
28
+
29
+ 1. Add the entity name to `ENTITIES` and a rule to `SPECS` in `src/rules.rs`.
30
+ 2. Use ASCII word boundaries (`(?-u)`). Unicode `\b` turns off the fast DFA.
31
+ 3. If the format has a checksum or reserved ranges, add a validator.
32
+ 4. Add tests for matches and for look-alikes that must be left alone, then add
33
+ the new detector's hostile input to `benches/bench.py`.
34
+ 5. Measure with `benches/accuracy.py --split dev`. Keep `--split heldout` for final
35
+ scores, so results aren't tuned to the test data.
36
+
37
+ ## Releasing
38
+
39
+ Update the version in `Cargo.toml` and the changelog in a pull request. After it
40
+ merges, push a `vX.Y.Z` tag from `master`.
41
+ The release workflow builds the wheels and publishes them to PyPI.
42
+
43
+ Never use real personal data in tests, issues or pull requests.
@@ -0,0 +1,179 @@
1
+ # This file is automatically @generated by Cargo.
2
+ # It is not intended for manual editing.
3
+ version = 4
4
+
5
+ [[package]]
6
+ name = "aho-corasick"
7
+ version = "1.1.5"
8
+ source = "registry+https://github.com/rust-lang/crates.io-index"
9
+ checksum = "c982642fa9e8606056828ee9a8505737230110bb1099153c79efe865c59d12ba"
10
+ dependencies = [
11
+ "memchr",
12
+ ]
13
+
14
+ [[package]]
15
+ name = "heck"
16
+ version = "0.5.0"
17
+ source = "registry+https://github.com/rust-lang/crates.io-index"
18
+ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
19
+
20
+ [[package]]
21
+ name = "libc"
22
+ version = "0.2.191"
23
+ source = "registry+https://github.com/rust-lang/crates.io-index"
24
+ checksum = "65cd87c9a6d60536580b316ad985726104730a5151c99845f2490428ef91240a"
25
+
26
+ [[package]]
27
+ name = "memchr"
28
+ version = "2.8.3"
29
+ source = "registry+https://github.com/rust-lang/crates.io-index"
30
+ checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98"
31
+
32
+ [[package]]
33
+ name = "once_cell"
34
+ version = "1.21.4"
35
+ source = "registry+https://github.com/rust-lang/crates.io-index"
36
+ checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
37
+
38
+ [[package]]
39
+ name = "piihush"
40
+ version = "0.1.0"
41
+ dependencies = [
42
+ "aho-corasick",
43
+ "memchr",
44
+ "pyo3",
45
+ "regex",
46
+ ]
47
+
48
+ [[package]]
49
+ name = "portable-atomic"
50
+ version = "1.15.0"
51
+ source = "registry+https://github.com/rust-lang/crates.io-index"
52
+ checksum = "05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85"
53
+
54
+ [[package]]
55
+ name = "proc-macro2"
56
+ version = "1.0.107"
57
+ source = "registry+https://github.com/rust-lang/crates.io-index"
58
+ checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9"
59
+ dependencies = [
60
+ "unicode-ident",
61
+ ]
62
+
63
+ [[package]]
64
+ name = "pyo3"
65
+ version = "0.30.1"
66
+ source = "registry+https://github.com/rust-lang/crates.io-index"
67
+ checksum = "229ca13b8a15bb0d1487b81ab975bfcd97513416499a8312011b6036e42e0de4"
68
+ dependencies = [
69
+ "libc",
70
+ "once_cell",
71
+ "portable-atomic",
72
+ "pyo3-build-config",
73
+ "pyo3-ffi",
74
+ "pyo3-macros",
75
+ ]
76
+
77
+ [[package]]
78
+ name = "pyo3-build-config"
79
+ version = "0.30.1"
80
+ source = "registry+https://github.com/rust-lang/crates.io-index"
81
+ checksum = "70130e2b6dd1ee589a8788026a429561ca5c40fa7a2fa7914c2282eddae24700"
82
+ dependencies = [
83
+ "target-lexicon",
84
+ ]
85
+
86
+ [[package]]
87
+ name = "pyo3-ffi"
88
+ version = "0.30.1"
89
+ source = "registry+https://github.com/rust-lang/crates.io-index"
90
+ checksum = "5e7ff73c555c286d212d4ce7e5fbda845a973c4f61bd5f160f5f2c3c2a04d1c4"
91
+ dependencies = [
92
+ "libc",
93
+ "pyo3-build-config",
94
+ ]
95
+
96
+ [[package]]
97
+ name = "pyo3-macros"
98
+ version = "0.30.1"
99
+ source = "registry+https://github.com/rust-lang/crates.io-index"
100
+ checksum = "c46d2e5862c7bb8207e3b639f713dda3c499933444784154c11d013c5a691b60"
101
+ dependencies = [
102
+ "proc-macro2",
103
+ "pyo3-macros-backend",
104
+ "quote",
105
+ "syn",
106
+ ]
107
+
108
+ [[package]]
109
+ name = "pyo3-macros-backend"
110
+ version = "0.30.1"
111
+ source = "registry+https://github.com/rust-lang/crates.io-index"
112
+ checksum = "38b89f066f2ae72a2aef52d1537ca2fcd104440ebfadee06e97aa90738a25b9b"
113
+ dependencies = [
114
+ "heck",
115
+ "proc-macro2",
116
+ "quote",
117
+ "syn",
118
+ ]
119
+
120
+ [[package]]
121
+ name = "quote"
122
+ version = "1.0.47"
123
+ source = "registry+https://github.com/rust-lang/crates.io-index"
124
+ checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001"
125
+ dependencies = [
126
+ "proc-macro2",
127
+ ]
128
+
129
+ [[package]]
130
+ name = "regex"
131
+ version = "1.13.1"
132
+ source = "registry+https://github.com/rust-lang/crates.io-index"
133
+ checksum = "f020237b6c8eed93db2e2cb53c00c60a8e1bc73da7d073199a1180401450218d"
134
+ dependencies = [
135
+ "aho-corasick",
136
+ "memchr",
137
+ "regex-automata",
138
+ "regex-syntax",
139
+ ]
140
+
141
+ [[package]]
142
+ name = "regex-automata"
143
+ version = "0.4.18"
144
+ source = "registry+https://github.com/rust-lang/crates.io-index"
145
+ checksum = "ad8553b9b26413251cbf30e620595c7a41b3887f03da04579c0e6b0d6a06b4b2"
146
+ dependencies = [
147
+ "aho-corasick",
148
+ "memchr",
149
+ "regex-syntax",
150
+ ]
151
+
152
+ [[package]]
153
+ name = "regex-syntax"
154
+ version = "0.8.11"
155
+ source = "registry+https://github.com/rust-lang/crates.io-index"
156
+ checksum = "d6f6ff9a378485b298a5286656da665ba74413d36db0979633275d2e708145d4"
157
+
158
+ [[package]]
159
+ name = "syn"
160
+ version = "3.0.9"
161
+ source = "registry+https://github.com/rust-lang/crates.io-index"
162
+ checksum = "d78c8dee4c7bf0e14673097256fed6142ce9d3b85a408189d07482442145823b"
163
+ dependencies = [
164
+ "proc-macro2",
165
+ "quote",
166
+ "unicode-ident",
167
+ ]
168
+
169
+ [[package]]
170
+ name = "target-lexicon"
171
+ version = "0.13.5"
172
+ source = "registry+https://github.com/rust-lang/crates.io-index"
173
+ checksum = "adb6935a6f5c20170eeceb1a3835a49e12e19d792f6dd344ccc76a985ca5a6ca"
174
+
175
+ [[package]]
176
+ name = "unicode-ident"
177
+ version = "1.0.27"
178
+ source = "registry+https://github.com/rust-lang/crates.io-index"
179
+ checksum = "a2c754d6c33795a1c324727428e5a7dedb5b06195f9890bdbcba760d3e246563"
@@ -0,0 +1,29 @@
1
+ [package]
2
+ name = "piihush"
3
+ version = "0.1.0"
4
+ edition = "2024"
5
+ description = "High-speed PII and secret masking for RAG and LLM pipelines"
6
+ license = "MIT"
7
+ readme = "README.md"
8
+ publish = false
9
+
10
+ [lib]
11
+ name = "piihush"
12
+ crate-type = ["cdylib", "rlib"]
13
+
14
+ [features]
15
+ # The engine is plain Rust. Only the wheel build enables the bindings, so
16
+ # `cargo test` works without a Python interpreter.
17
+ python = ["dep:pyo3"]
18
+
19
+ [dependencies]
20
+ aho-corasick = "1.1"
21
+ memchr = "2.8"
22
+ pyo3 = { version = "0.30", features = ["abi3-py311"], optional = true }
23
+ regex = "1.13"
24
+
25
+ [profile.release]
26
+ lto = "fat"
27
+ codegen-units = 1
28
+ panic = "abort"
29
+ strip = true
piihush-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Dennis K
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.