SqueakyCleanText 0.6.1__tar.gz → 0.7.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.
Files changed (56) hide show
  1. {squeakycleantext-0.6.1 → squeakycleantext-0.7.0}/PKG-INFO +138 -7
  2. {squeakycleantext-0.6.1 → squeakycleantext-0.7.0}/README.md +130 -1
  3. {squeakycleantext-0.6.1 → squeakycleantext-0.7.0}/SqueakyCleanText.egg-info/PKG-INFO +138 -7
  4. {squeakycleantext-0.6.1 → squeakycleantext-0.7.0}/SqueakyCleanText.egg-info/SOURCES.txt +24 -1
  5. squeakycleantext-0.7.0/SqueakyCleanText.egg-info/entry_points.txt +3 -0
  6. {squeakycleantext-0.6.1 → squeakycleantext-0.7.0}/SqueakyCleanText.egg-info/requires.txt +7 -4
  7. {squeakycleantext-0.6.1 → squeakycleantext-0.7.0}/pyproject.toml +13 -6
  8. squeakycleantext-0.7.0/sct/__init__.py +71 -0
  9. squeakycleantext-0.7.0/sct/adapters.py +215 -0
  10. squeakycleantext-0.7.0/sct/browser.py +123 -0
  11. squeakycleantext-0.7.0/sct/cli.py +101 -0
  12. {squeakycleantext-0.6.1 → squeakycleantext-0.7.0}/sct/config.py +93 -7
  13. squeakycleantext-0.7.0/sct/evaluation.py +209 -0
  14. squeakycleantext-0.7.0/sct/mcp_server.py +104 -0
  15. squeakycleantext-0.7.0/sct/model_benchmark.py +173 -0
  16. squeakycleantext-0.7.0/sct/model_candidates.py +89 -0
  17. squeakycleantext-0.7.0/sct/ocr.py +123 -0
  18. squeakycleantext-0.7.0/sct/privacy.py +169 -0
  19. squeakycleantext-0.7.0/sct/risk.py +58 -0
  20. {squeakycleantext-0.6.1 → squeakycleantext-0.7.0}/sct/sct.py +222 -11
  21. squeakycleantext-0.7.0/sct/streaming.py +87 -0
  22. {squeakycleantext-0.6.1 → squeakycleantext-0.7.0}/sct/utils/contact.py +1 -10
  23. {squeakycleantext-0.6.1 → squeakycleantext-0.7.0}/sct/utils/gliclass_adapter.py +10 -8
  24. {squeakycleantext-0.6.1 → squeakycleantext-0.7.0}/sct/utils/gliner_adapter.py +6 -3
  25. {squeakycleantext-0.6.1 → squeakycleantext-0.7.0}/sct/utils/ner.py +186 -13
  26. {squeakycleantext-0.6.1 → squeakycleantext-0.7.0}/sct/utils/onnx_pipeline.py +3 -0
  27. {squeakycleantext-0.6.1 → squeakycleantext-0.7.0}/sct/utils/process_result.py +3 -0
  28. {squeakycleantext-0.6.1 → squeakycleantext-0.7.0}/sct/utils/torch_pipeline.py +11 -2
  29. squeakycleantext-0.7.0/tests/test_adapters.py +104 -0
  30. squeakycleantext-0.7.0/tests/test_browser.py +37 -0
  31. squeakycleantext-0.7.0/tests/test_cli.py +79 -0
  32. squeakycleantext-0.7.0/tests/test_contracts.py +136 -0
  33. squeakycleantext-0.7.0/tests/test_evaluation.py +129 -0
  34. squeakycleantext-0.7.0/tests/test_mcp_server.py +95 -0
  35. squeakycleantext-0.7.0/tests/test_model_benchmarks.py +119 -0
  36. squeakycleantext-0.7.0/tests/test_ocr.py +87 -0
  37. squeakycleantext-0.7.0/tests/test_privacy.py +334 -0
  38. squeakycleantext-0.7.0/tests/test_risk.py +21 -0
  39. squeakycleantext-0.7.0/tests/test_streaming.py +34 -0
  40. squeakycleantext-0.6.1/sct/__init__.py +0 -13
  41. {squeakycleantext-0.6.1 → squeakycleantext-0.7.0}/LICENSE +0 -0
  42. {squeakycleantext-0.6.1 → squeakycleantext-0.7.0}/SqueakyCleanText.egg-info/dependency_links.txt +0 -0
  43. {squeakycleantext-0.6.1 → squeakycleantext-0.7.0}/SqueakyCleanText.egg-info/top_level.txt +0 -0
  44. {squeakycleantext-0.6.1 → squeakycleantext-0.7.0}/sct/utils/__init__.py +0 -0
  45. {squeakycleantext-0.6.1 → squeakycleantext-0.7.0}/sct/utils/anonymization_map.py +0 -0
  46. {squeakycleantext-0.6.1 → squeakycleantext-0.7.0}/sct/utils/constants.py +0 -0
  47. {squeakycleantext-0.6.1 → squeakycleantext-0.7.0}/sct/utils/datetime.py +0 -0
  48. {squeakycleantext-0.6.1 → squeakycleantext-0.7.0}/sct/utils/normtext.py +0 -0
  49. {squeakycleantext-0.6.1 → squeakycleantext-0.7.0}/sct/utils/resources.py +0 -0
  50. {squeakycleantext-0.6.1 → squeakycleantext-0.7.0}/sct/utils/special.py +0 -0
  51. {squeakycleantext-0.6.1 → squeakycleantext-0.7.0}/sct/utils/stopwords.py +0 -0
  52. {squeakycleantext-0.6.1 → squeakycleantext-0.7.0}/sct/utils/synthetic.py +0 -0
  53. {squeakycleantext-0.6.1 → squeakycleantext-0.7.0}/setup.cfg +0 -0
  54. {squeakycleantext-0.6.1 → squeakycleantext-0.7.0}/setup.py +0 -0
  55. {squeakycleantext-0.6.1 → squeakycleantext-0.7.0}/tests/test_functional.py +0 -0
  56. {squeakycleantext-0.6.1 → squeakycleantext-0.7.0}/tests/test_sct.py +0 -0
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: SqueakyCleanText
3
- Version: 0.6.1
3
+ Version: 0.7.0
4
4
  Summary: Text preprocessing & PII anonymization pipeline for NLP/ML: ONNX NER ensemble, language detection, stopword removal, and configurable token replacement.
5
5
  Author: Rehan Fazal
6
- License: MIT
6
+ License-Expression: MIT
7
7
  Project-URL: Homepage, https://github.com/rhnfzl/SqueakyCleanText
8
8
  Project-URL: Repository, https://github.com/rhnfzl/SqueakyCleanText
9
9
  Project-URL: Issues, https://github.com/rhnfzl/SqueakyCleanText/issues
@@ -22,7 +22,7 @@ Classifier: Programming Language :: Python :: 3
22
22
  Classifier: Programming Language :: Python :: 3.11
23
23
  Classifier: Programming Language :: Python :: 3.12
24
24
  Classifier: Programming Language :: Python :: 3.13
25
- Classifier: License :: OSI Approved :: MIT License
25
+ Classifier: Programming Language :: Python :: 3.14
26
26
  Classifier: Operating System :: OS Independent
27
27
  Requires-Python: >=3.11
28
28
  Description-Content-Type: text/markdown
@@ -32,7 +32,6 @@ Requires-Dist: stop-words>=2025.11.4
32
32
  Requires-Dist: emoji>=2.14
33
33
  Requires-Dist: ftfy>=6.3
34
34
  Requires-Dist: Unidecode>=1.4
35
- Requires-Dist: beautifulsoup4>=4.14
36
35
  Requires-Dist: onnxruntime>=1.24.2
37
36
  Requires-Dist: tokenizers>=0.22.2
38
37
  Requires-Dist: huggingface-hub>=1.5.0
@@ -56,8 +55,6 @@ Provides-Extra: presidio
56
55
  Requires-Dist: presidio-analyzer>=2.2.360; extra == "presidio"
57
56
  Provides-Extra: classify
58
57
  Requires-Dist: gliclass>=0.1.16; extra == "classify"
59
- Provides-Extra: classify-onnx
60
- Requires-Dist: onnxruntime>=1.24.2; extra == "classify-onnx"
61
58
  Provides-Extra: all-ner
62
59
  Requires-Dist: torch>=2.6.0; extra == "all-ner"
63
60
  Requires-Dist: transformers>=4.48; extra == "all-ner"
@@ -73,6 +70,11 @@ Requires-Dist: rapidfuzz>=3.12; extra == "dev"
73
70
  Provides-Extra: test
74
71
  Requires-Dist: coverage>=7.8; extra == "test"
75
72
  Requires-Dist: pytest-cov>=6.0; extra == "test"
73
+ Provides-Extra: mcp
74
+ Requires-Dist: fastmcp>=4.0.5; extra == "mcp"
75
+ Provides-Extra: ocr
76
+ Requires-Dist: pillow>=12.3.0; extra == "ocr"
77
+ Requires-Dist: pytesseract>=0.3.13; extra == "ocr"
76
78
  Dynamic: license-file
77
79
 
78
80
  <div align="center">
@@ -82,7 +84,7 @@ Dynamic: license-file
82
84
  [![PyPI](https://img.shields.io/pypi/v/squeakycleantext.svg)](https://pypi.org/project/squeakycleantext/)
83
85
  [![PyPI - Downloads](https://img.shields.io/pypi/dm/squeakycleantext)](https://pypistats.org/packages/squeakycleantext)
84
86
  [![Python package](https://github.com/rhnfzl/SqueakyCleanText/actions/workflows/python-package.yml/badge.svg)](https://github.com/rhnfzl/SqueakyCleanText/actions/workflows/python-package.yml)
85
- [![Python Versions](https://img.shields.io/badge/Python-3.11%20|%203.12%20|%203.13-blue)](https://pypi.org/project/squeakycleantext/)
87
+ [![Python Versions](https://img.shields.io/badge/Python-3.11%20|%203.12%20|%203.13%20|%203.14-blue)](https://pypi.org/project/squeakycleantext/)
86
88
  [![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
87
89
 
88
90
  A comprehensive text cleaning and preprocessing pipeline for machine learning and NLP tasks.
@@ -179,6 +181,8 @@ The base install uses **ONNX Runtime** for NER inference - no PyTorch or Transfo
179
181
  | Synthetic | `pip install SqueakyCleanText[synthetic]` | Faker-based synthetic replacement (realistic fake values instead of `<TAG>` tokens) |
180
182
  | Presidio | `pip install SqueakyCleanText[presidio]` | Presidio-analyzer for `presidio_gliner` backend |
181
183
  | Classify | `pip install SqueakyCleanText[classify]` | GLiClass document-level pre-classification |
184
+ | MCP | `pip install SqueakyCleanText[mcp]` | FastMCP server with text and JSON cleaning tools |
185
+ | OCR | `pip install SqueakyCleanText[ocr]` | Pillow image redaction and Tesseract OCR adapter |
182
186
  | All NER | `pip install SqueakyCleanText[all-ner]` | All NER backends combined |
183
187
  | Development | `pip install SqueakyCleanText[dev]` | Testing and linting tools |
184
188
 
@@ -653,6 +657,116 @@ new_cfg = dataclasses.replace(cfg, check_ner_process=False)
653
657
 
654
658
  </details>
655
659
 
660
+ ## Privacy Engine
661
+
662
+ Applications can apply versioned policy rules and inspect each decision.
663
+ This makes privacy behavior testable across services, datasets, and model upgrades.
664
+
665
+ ```python
666
+ from sct import EntityRule, PrivacyPolicy, TextCleaner, TextCleanerConfig
667
+
668
+ policy = PrivacyPolicy(
669
+ name="support-export",
670
+ version="1",
671
+ rules={
672
+ "PERSON": EntityRule(action="redact", min_score=0.8),
673
+ "ORGANISATION": EntityRule(action="keep"),
674
+ },
675
+ allowlist=frozenset({"Jane Public"}),
676
+ )
677
+
678
+ cleaner = TextCleaner(
679
+ cfg=TextCleanerConfig(ner_mode="pii"),
680
+ privacy_policy=policy,
681
+ include_entities=True,
682
+ )
683
+ result = cleaner.process("Contact Maria Chen for help.")
684
+
685
+ print(result.metadata["findings"])
686
+ print(result.metadata["detector"])
687
+ ```
688
+
689
+ Reversible output is pseudonymized personal data. Anyone with the token map can
690
+ restore the source values. Keep token maps outside logs and cleaned datasets.
691
+
692
+ Use a `TokenStore` implementation to keep maps behind opaque references:
693
+
694
+ ```python
695
+ from sct import InMemoryTokenStore, TextCleaner, TextCleanerConfig
696
+
697
+ store = InMemoryTokenStore()
698
+ cleaner = TextCleaner(
699
+ cfg=TextCleanerConfig(replacement_mode="reversible"),
700
+ token_store=store,
701
+ )
702
+ result = cleaner.process("Maria lives in Utrecht.")
703
+ reference = result.metadata["anon_map_reference"]
704
+ ```
705
+
706
+ `InMemoryTokenStore` supports tests and short sessions. Production systems
707
+ should implement `TokenStore` with encryption, access control, expiry, and audit logs.
708
+
709
+ ### Boundary adapters
710
+
711
+ The base package includes JSON, DataFrame, retrieval, command-line, and streaming adapters:
712
+
713
+ ```python
714
+ from sct import RAGChunk, process_json, process_rag_chunks
715
+
716
+ cleaned_json = process_json(cleaner, {"message": "Email a@example.com"})
717
+ cleaned_chunks = process_rag_chunks(
718
+ cleaner,
719
+ [RAGChunk(id="1", text="Call +1-202-555-0147", metadata={})],
720
+ )
721
+ ```
722
+
723
+ ```sh
724
+ printf 'Email maria@example.com' | sct-clean --no-ner
725
+ printf 'Email maria@example.com' | sct-clean --no-ner \
726
+ --replacement-mode reversible --token-map tokens.json
727
+ pip install 'SqueakyCleanText[mcp]'
728
+ sct-mcp
729
+ ```
730
+
731
+ `BufferedStreamingRedactor` holds a full document for cross-chunk NER safety.
732
+ `WindowedStreamingRedactor` provides bounded latency for contact tokens.
733
+
734
+ The OCR adapter accepts any `OCRProvider`. The included Tesseract provider also
735
+ needs a local Tesseract executable. Browser export writes an ONNX Runtime Web
736
+ manifest, but it does not copy model files or Python language detection.
737
+
738
+ Corpus owners can call `assess_reidentification_risk` to measure k-anonymity
739
+ for selected quasi-identifiers. Reports contain counts only, not source values.
740
+
741
+ ## PII Evaluation
742
+
743
+ Model changes need ground-truth privacy evaluation, not only backend agreement.
744
+ The evaluation harness reports exact entity metrics by label, language, domain,
745
+ and named slice.
746
+
747
+ ```sh
748
+ python -m scripts.evaluate_pii \
749
+ --dataset evaluation/pii_starter.jsonl \
750
+ --predictions path/to/model-predictions.jsonl \
751
+ --model model-name-and-revision \
752
+ --output evaluation/results/model-name.json
753
+ ```
754
+
755
+ The included starter corpus is synthetic and only checks the evaluation path.
756
+ See [`evaluation/README.md`](evaluation/README.md) for schemas and release rules.
757
+
758
+ Pinned candidates live in `sct.model_candidates`. Run one candidate with:
759
+
760
+ ```sh
761
+ python -m scripts.benchmark_models \
762
+ --dataset evaluation/pii_starter.jsonl \
763
+ --candidate gliner2-pii \
764
+ --output evaluation/results/gliner2-pii.json
765
+ ```
766
+
767
+ Published third-party results are reference data only. `assess_candidate`
768
+ requires local recall, exact-span F1, latency, and ONNX parity before adoption.
769
+
656
770
  ## Architecture
657
771
 
658
772
  SqueakyCleanText processes text through a configurable pipeline of sequential steps:
@@ -690,6 +804,23 @@ Each step is toggled by a `TextCleanerConfig` field. The pipeline is built once
690
804
 
691
805
  ## What's New
692
806
 
807
+ **v0.7.0**
808
+ - **Privacy policies**: Apply versioned entity rules, allowlists, thresholds, and redaction actions.
809
+ - **Structured audit findings**: Inspect entity decisions, detector backends, and pinned model revisions.
810
+ - **Safer reversible processing**: Restore contact values and keep token maps behind an optional `TokenStore`.
811
+ - **Boundary adapters**: Clean JSON, DataFrame-like objects, RAG chunks, standard input, and MCP tool requests.
812
+ - **Privacy evaluation**: Score exact PII spans by label, language, domain, and custom slice.
813
+ - **Model adoption gates**: Compare pinned candidates using recall, F1, latency, and ONNX parity.
814
+ - **Extended media support**: Redact OCR regions, process bounded streams, and export browser deployment manifests.
815
+ - **Corpus risk indicators**: Measure k-anonymity for user-selected quasi-identifiers.
816
+ - **Supply-chain improvements**: Pin model revisions, publish through PyPI Trusted Publishing, and ship standard lockfiles.
817
+ - **Python 3.14**: Added CI coverage alongside Python 3.11 through 3.13.
818
+
819
+ Migration notes:
820
+ - `gliclass_onnx=True` now raises an error because the upstream package has no native ONNX loader.
821
+ - HTML processing now honors `replace_with_html` instead of silently stripping tags.
822
+ - Structured adapters reject reversible mode unless each token map can be retained safely.
823
+
693
824
  **v0.6.0**
694
825
  - **PII detection mode** (`ner_mode='pii'`): auto-configures GLiNER with 60+ PII entity labels (personal, financial, healthcare, identity, digital)
695
826
  - **Synthetic replacement** (`replacement_mode='synthetic'`): Faker-generated realistic values instead of `<TAG>` placeholders, with per-document consistency
@@ -5,7 +5,7 @@
5
5
  [![PyPI](https://img.shields.io/pypi/v/squeakycleantext.svg)](https://pypi.org/project/squeakycleantext/)
6
6
  [![PyPI - Downloads](https://img.shields.io/pypi/dm/squeakycleantext)](https://pypistats.org/packages/squeakycleantext)
7
7
  [![Python package](https://github.com/rhnfzl/SqueakyCleanText/actions/workflows/python-package.yml/badge.svg)](https://github.com/rhnfzl/SqueakyCleanText/actions/workflows/python-package.yml)
8
- [![Python Versions](https://img.shields.io/badge/Python-3.11%20|%203.12%20|%203.13-blue)](https://pypi.org/project/squeakycleantext/)
8
+ [![Python Versions](https://img.shields.io/badge/Python-3.11%20|%203.12%20|%203.13%20|%203.14-blue)](https://pypi.org/project/squeakycleantext/)
9
9
  [![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
10
10
 
11
11
  A comprehensive text cleaning and preprocessing pipeline for machine learning and NLP tasks.
@@ -102,6 +102,8 @@ The base install uses **ONNX Runtime** for NER inference - no PyTorch or Transfo
102
102
  | Synthetic | `pip install SqueakyCleanText[synthetic]` | Faker-based synthetic replacement (realistic fake values instead of `<TAG>` tokens) |
103
103
  | Presidio | `pip install SqueakyCleanText[presidio]` | Presidio-analyzer for `presidio_gliner` backend |
104
104
  | Classify | `pip install SqueakyCleanText[classify]` | GLiClass document-level pre-classification |
105
+ | MCP | `pip install SqueakyCleanText[mcp]` | FastMCP server with text and JSON cleaning tools |
106
+ | OCR | `pip install SqueakyCleanText[ocr]` | Pillow image redaction and Tesseract OCR adapter |
105
107
  | All NER | `pip install SqueakyCleanText[all-ner]` | All NER backends combined |
106
108
  | Development | `pip install SqueakyCleanText[dev]` | Testing and linting tools |
107
109
 
@@ -576,6 +578,116 @@ new_cfg = dataclasses.replace(cfg, check_ner_process=False)
576
578
 
577
579
  </details>
578
580
 
581
+ ## Privacy Engine
582
+
583
+ Applications can apply versioned policy rules and inspect each decision.
584
+ This makes privacy behavior testable across services, datasets, and model upgrades.
585
+
586
+ ```python
587
+ from sct import EntityRule, PrivacyPolicy, TextCleaner, TextCleanerConfig
588
+
589
+ policy = PrivacyPolicy(
590
+ name="support-export",
591
+ version="1",
592
+ rules={
593
+ "PERSON": EntityRule(action="redact", min_score=0.8),
594
+ "ORGANISATION": EntityRule(action="keep"),
595
+ },
596
+ allowlist=frozenset({"Jane Public"}),
597
+ )
598
+
599
+ cleaner = TextCleaner(
600
+ cfg=TextCleanerConfig(ner_mode="pii"),
601
+ privacy_policy=policy,
602
+ include_entities=True,
603
+ )
604
+ result = cleaner.process("Contact Maria Chen for help.")
605
+
606
+ print(result.metadata["findings"])
607
+ print(result.metadata["detector"])
608
+ ```
609
+
610
+ Reversible output is pseudonymized personal data. Anyone with the token map can
611
+ restore the source values. Keep token maps outside logs and cleaned datasets.
612
+
613
+ Use a `TokenStore` implementation to keep maps behind opaque references:
614
+
615
+ ```python
616
+ from sct import InMemoryTokenStore, TextCleaner, TextCleanerConfig
617
+
618
+ store = InMemoryTokenStore()
619
+ cleaner = TextCleaner(
620
+ cfg=TextCleanerConfig(replacement_mode="reversible"),
621
+ token_store=store,
622
+ )
623
+ result = cleaner.process("Maria lives in Utrecht.")
624
+ reference = result.metadata["anon_map_reference"]
625
+ ```
626
+
627
+ `InMemoryTokenStore` supports tests and short sessions. Production systems
628
+ should implement `TokenStore` with encryption, access control, expiry, and audit logs.
629
+
630
+ ### Boundary adapters
631
+
632
+ The base package includes JSON, DataFrame, retrieval, command-line, and streaming adapters:
633
+
634
+ ```python
635
+ from sct import RAGChunk, process_json, process_rag_chunks
636
+
637
+ cleaned_json = process_json(cleaner, {"message": "Email a@example.com"})
638
+ cleaned_chunks = process_rag_chunks(
639
+ cleaner,
640
+ [RAGChunk(id="1", text="Call +1-202-555-0147", metadata={})],
641
+ )
642
+ ```
643
+
644
+ ```sh
645
+ printf 'Email maria@example.com' | sct-clean --no-ner
646
+ printf 'Email maria@example.com' | sct-clean --no-ner \
647
+ --replacement-mode reversible --token-map tokens.json
648
+ pip install 'SqueakyCleanText[mcp]'
649
+ sct-mcp
650
+ ```
651
+
652
+ `BufferedStreamingRedactor` holds a full document for cross-chunk NER safety.
653
+ `WindowedStreamingRedactor` provides bounded latency for contact tokens.
654
+
655
+ The OCR adapter accepts any `OCRProvider`. The included Tesseract provider also
656
+ needs a local Tesseract executable. Browser export writes an ONNX Runtime Web
657
+ manifest, but it does not copy model files or Python language detection.
658
+
659
+ Corpus owners can call `assess_reidentification_risk` to measure k-anonymity
660
+ for selected quasi-identifiers. Reports contain counts only, not source values.
661
+
662
+ ## PII Evaluation
663
+
664
+ Model changes need ground-truth privacy evaluation, not only backend agreement.
665
+ The evaluation harness reports exact entity metrics by label, language, domain,
666
+ and named slice.
667
+
668
+ ```sh
669
+ python -m scripts.evaluate_pii \
670
+ --dataset evaluation/pii_starter.jsonl \
671
+ --predictions path/to/model-predictions.jsonl \
672
+ --model model-name-and-revision \
673
+ --output evaluation/results/model-name.json
674
+ ```
675
+
676
+ The included starter corpus is synthetic and only checks the evaluation path.
677
+ See [`evaluation/README.md`](evaluation/README.md) for schemas and release rules.
678
+
679
+ Pinned candidates live in `sct.model_candidates`. Run one candidate with:
680
+
681
+ ```sh
682
+ python -m scripts.benchmark_models \
683
+ --dataset evaluation/pii_starter.jsonl \
684
+ --candidate gliner2-pii \
685
+ --output evaluation/results/gliner2-pii.json
686
+ ```
687
+
688
+ Published third-party results are reference data only. `assess_candidate`
689
+ requires local recall, exact-span F1, latency, and ONNX parity before adoption.
690
+
579
691
  ## Architecture
580
692
 
581
693
  SqueakyCleanText processes text through a configurable pipeline of sequential steps:
@@ -613,6 +725,23 @@ Each step is toggled by a `TextCleanerConfig` field. The pipeline is built once
613
725
 
614
726
  ## What's New
615
727
 
728
+ **v0.7.0**
729
+ - **Privacy policies**: Apply versioned entity rules, allowlists, thresholds, and redaction actions.
730
+ - **Structured audit findings**: Inspect entity decisions, detector backends, and pinned model revisions.
731
+ - **Safer reversible processing**: Restore contact values and keep token maps behind an optional `TokenStore`.
732
+ - **Boundary adapters**: Clean JSON, DataFrame-like objects, RAG chunks, standard input, and MCP tool requests.
733
+ - **Privacy evaluation**: Score exact PII spans by label, language, domain, and custom slice.
734
+ - **Model adoption gates**: Compare pinned candidates using recall, F1, latency, and ONNX parity.
735
+ - **Extended media support**: Redact OCR regions, process bounded streams, and export browser deployment manifests.
736
+ - **Corpus risk indicators**: Measure k-anonymity for user-selected quasi-identifiers.
737
+ - **Supply-chain improvements**: Pin model revisions, publish through PyPI Trusted Publishing, and ship standard lockfiles.
738
+ - **Python 3.14**: Added CI coverage alongside Python 3.11 through 3.13.
739
+
740
+ Migration notes:
741
+ - `gliclass_onnx=True` now raises an error because the upstream package has no native ONNX loader.
742
+ - HTML processing now honors `replace_with_html` instead of silently stripping tags.
743
+ - Structured adapters reject reversible mode unless each token map can be retained safely.
744
+
616
745
  **v0.6.0**
617
746
  - **PII detection mode** (`ner_mode='pii'`): auto-configures GLiNER with 60+ PII entity labels (personal, financial, healthcare, identity, digital)
618
747
  - **Synthetic replacement** (`replacement_mode='synthetic'`): Faker-generated realistic values instead of `<TAG>` placeholders, with per-document consistency
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: SqueakyCleanText
3
- Version: 0.6.1
3
+ Version: 0.7.0
4
4
  Summary: Text preprocessing & PII anonymization pipeline for NLP/ML: ONNX NER ensemble, language detection, stopword removal, and configurable token replacement.
5
5
  Author: Rehan Fazal
6
- License: MIT
6
+ License-Expression: MIT
7
7
  Project-URL: Homepage, https://github.com/rhnfzl/SqueakyCleanText
8
8
  Project-URL: Repository, https://github.com/rhnfzl/SqueakyCleanText
9
9
  Project-URL: Issues, https://github.com/rhnfzl/SqueakyCleanText/issues
@@ -22,7 +22,7 @@ Classifier: Programming Language :: Python :: 3
22
22
  Classifier: Programming Language :: Python :: 3.11
23
23
  Classifier: Programming Language :: Python :: 3.12
24
24
  Classifier: Programming Language :: Python :: 3.13
25
- Classifier: License :: OSI Approved :: MIT License
25
+ Classifier: Programming Language :: Python :: 3.14
26
26
  Classifier: Operating System :: OS Independent
27
27
  Requires-Python: >=3.11
28
28
  Description-Content-Type: text/markdown
@@ -32,7 +32,6 @@ Requires-Dist: stop-words>=2025.11.4
32
32
  Requires-Dist: emoji>=2.14
33
33
  Requires-Dist: ftfy>=6.3
34
34
  Requires-Dist: Unidecode>=1.4
35
- Requires-Dist: beautifulsoup4>=4.14
36
35
  Requires-Dist: onnxruntime>=1.24.2
37
36
  Requires-Dist: tokenizers>=0.22.2
38
37
  Requires-Dist: huggingface-hub>=1.5.0
@@ -56,8 +55,6 @@ Provides-Extra: presidio
56
55
  Requires-Dist: presidio-analyzer>=2.2.360; extra == "presidio"
57
56
  Provides-Extra: classify
58
57
  Requires-Dist: gliclass>=0.1.16; extra == "classify"
59
- Provides-Extra: classify-onnx
60
- Requires-Dist: onnxruntime>=1.24.2; extra == "classify-onnx"
61
58
  Provides-Extra: all-ner
62
59
  Requires-Dist: torch>=2.6.0; extra == "all-ner"
63
60
  Requires-Dist: transformers>=4.48; extra == "all-ner"
@@ -73,6 +70,11 @@ Requires-Dist: rapidfuzz>=3.12; extra == "dev"
73
70
  Provides-Extra: test
74
71
  Requires-Dist: coverage>=7.8; extra == "test"
75
72
  Requires-Dist: pytest-cov>=6.0; extra == "test"
73
+ Provides-Extra: mcp
74
+ Requires-Dist: fastmcp>=4.0.5; extra == "mcp"
75
+ Provides-Extra: ocr
76
+ Requires-Dist: pillow>=12.3.0; extra == "ocr"
77
+ Requires-Dist: pytesseract>=0.3.13; extra == "ocr"
76
78
  Dynamic: license-file
77
79
 
78
80
  <div align="center">
@@ -82,7 +84,7 @@ Dynamic: license-file
82
84
  [![PyPI](https://img.shields.io/pypi/v/squeakycleantext.svg)](https://pypi.org/project/squeakycleantext/)
83
85
  [![PyPI - Downloads](https://img.shields.io/pypi/dm/squeakycleantext)](https://pypistats.org/packages/squeakycleantext)
84
86
  [![Python package](https://github.com/rhnfzl/SqueakyCleanText/actions/workflows/python-package.yml/badge.svg)](https://github.com/rhnfzl/SqueakyCleanText/actions/workflows/python-package.yml)
85
- [![Python Versions](https://img.shields.io/badge/Python-3.11%20|%203.12%20|%203.13-blue)](https://pypi.org/project/squeakycleantext/)
87
+ [![Python Versions](https://img.shields.io/badge/Python-3.11%20|%203.12%20|%203.13%20|%203.14-blue)](https://pypi.org/project/squeakycleantext/)
86
88
  [![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
87
89
 
88
90
  A comprehensive text cleaning and preprocessing pipeline for machine learning and NLP tasks.
@@ -179,6 +181,8 @@ The base install uses **ONNX Runtime** for NER inference - no PyTorch or Transfo
179
181
  | Synthetic | `pip install SqueakyCleanText[synthetic]` | Faker-based synthetic replacement (realistic fake values instead of `<TAG>` tokens) |
180
182
  | Presidio | `pip install SqueakyCleanText[presidio]` | Presidio-analyzer for `presidio_gliner` backend |
181
183
  | Classify | `pip install SqueakyCleanText[classify]` | GLiClass document-level pre-classification |
184
+ | MCP | `pip install SqueakyCleanText[mcp]` | FastMCP server with text and JSON cleaning tools |
185
+ | OCR | `pip install SqueakyCleanText[ocr]` | Pillow image redaction and Tesseract OCR adapter |
182
186
  | All NER | `pip install SqueakyCleanText[all-ner]` | All NER backends combined |
183
187
  | Development | `pip install SqueakyCleanText[dev]` | Testing and linting tools |
184
188
 
@@ -653,6 +657,116 @@ new_cfg = dataclasses.replace(cfg, check_ner_process=False)
653
657
 
654
658
  </details>
655
659
 
660
+ ## Privacy Engine
661
+
662
+ Applications can apply versioned policy rules and inspect each decision.
663
+ This makes privacy behavior testable across services, datasets, and model upgrades.
664
+
665
+ ```python
666
+ from sct import EntityRule, PrivacyPolicy, TextCleaner, TextCleanerConfig
667
+
668
+ policy = PrivacyPolicy(
669
+ name="support-export",
670
+ version="1",
671
+ rules={
672
+ "PERSON": EntityRule(action="redact", min_score=0.8),
673
+ "ORGANISATION": EntityRule(action="keep"),
674
+ },
675
+ allowlist=frozenset({"Jane Public"}),
676
+ )
677
+
678
+ cleaner = TextCleaner(
679
+ cfg=TextCleanerConfig(ner_mode="pii"),
680
+ privacy_policy=policy,
681
+ include_entities=True,
682
+ )
683
+ result = cleaner.process("Contact Maria Chen for help.")
684
+
685
+ print(result.metadata["findings"])
686
+ print(result.metadata["detector"])
687
+ ```
688
+
689
+ Reversible output is pseudonymized personal data. Anyone with the token map can
690
+ restore the source values. Keep token maps outside logs and cleaned datasets.
691
+
692
+ Use a `TokenStore` implementation to keep maps behind opaque references:
693
+
694
+ ```python
695
+ from sct import InMemoryTokenStore, TextCleaner, TextCleanerConfig
696
+
697
+ store = InMemoryTokenStore()
698
+ cleaner = TextCleaner(
699
+ cfg=TextCleanerConfig(replacement_mode="reversible"),
700
+ token_store=store,
701
+ )
702
+ result = cleaner.process("Maria lives in Utrecht.")
703
+ reference = result.metadata["anon_map_reference"]
704
+ ```
705
+
706
+ `InMemoryTokenStore` supports tests and short sessions. Production systems
707
+ should implement `TokenStore` with encryption, access control, expiry, and audit logs.
708
+
709
+ ### Boundary adapters
710
+
711
+ The base package includes JSON, DataFrame, retrieval, command-line, and streaming adapters:
712
+
713
+ ```python
714
+ from sct import RAGChunk, process_json, process_rag_chunks
715
+
716
+ cleaned_json = process_json(cleaner, {"message": "Email a@example.com"})
717
+ cleaned_chunks = process_rag_chunks(
718
+ cleaner,
719
+ [RAGChunk(id="1", text="Call +1-202-555-0147", metadata={})],
720
+ )
721
+ ```
722
+
723
+ ```sh
724
+ printf 'Email maria@example.com' | sct-clean --no-ner
725
+ printf 'Email maria@example.com' | sct-clean --no-ner \
726
+ --replacement-mode reversible --token-map tokens.json
727
+ pip install 'SqueakyCleanText[mcp]'
728
+ sct-mcp
729
+ ```
730
+
731
+ `BufferedStreamingRedactor` holds a full document for cross-chunk NER safety.
732
+ `WindowedStreamingRedactor` provides bounded latency for contact tokens.
733
+
734
+ The OCR adapter accepts any `OCRProvider`. The included Tesseract provider also
735
+ needs a local Tesseract executable. Browser export writes an ONNX Runtime Web
736
+ manifest, but it does not copy model files or Python language detection.
737
+
738
+ Corpus owners can call `assess_reidentification_risk` to measure k-anonymity
739
+ for selected quasi-identifiers. Reports contain counts only, not source values.
740
+
741
+ ## PII Evaluation
742
+
743
+ Model changes need ground-truth privacy evaluation, not only backend agreement.
744
+ The evaluation harness reports exact entity metrics by label, language, domain,
745
+ and named slice.
746
+
747
+ ```sh
748
+ python -m scripts.evaluate_pii \
749
+ --dataset evaluation/pii_starter.jsonl \
750
+ --predictions path/to/model-predictions.jsonl \
751
+ --model model-name-and-revision \
752
+ --output evaluation/results/model-name.json
753
+ ```
754
+
755
+ The included starter corpus is synthetic and only checks the evaluation path.
756
+ See [`evaluation/README.md`](evaluation/README.md) for schemas and release rules.
757
+
758
+ Pinned candidates live in `sct.model_candidates`. Run one candidate with:
759
+
760
+ ```sh
761
+ python -m scripts.benchmark_models \
762
+ --dataset evaluation/pii_starter.jsonl \
763
+ --candidate gliner2-pii \
764
+ --output evaluation/results/gliner2-pii.json
765
+ ```
766
+
767
+ Published third-party results are reference data only. `assess_candidate`
768
+ requires local recall, exact-span F1, latency, and ONNX parity before adoption.
769
+
656
770
  ## Architecture
657
771
 
658
772
  SqueakyCleanText processes text through a configurable pipeline of sequential steps:
@@ -690,6 +804,23 @@ Each step is toggled by a `TextCleanerConfig` field. The pipeline is built once
690
804
 
691
805
  ## What's New
692
806
 
807
+ **v0.7.0**
808
+ - **Privacy policies**: Apply versioned entity rules, allowlists, thresholds, and redaction actions.
809
+ - **Structured audit findings**: Inspect entity decisions, detector backends, and pinned model revisions.
810
+ - **Safer reversible processing**: Restore contact values and keep token maps behind an optional `TokenStore`.
811
+ - **Boundary adapters**: Clean JSON, DataFrame-like objects, RAG chunks, standard input, and MCP tool requests.
812
+ - **Privacy evaluation**: Score exact PII spans by label, language, domain, and custom slice.
813
+ - **Model adoption gates**: Compare pinned candidates using recall, F1, latency, and ONNX parity.
814
+ - **Extended media support**: Redact OCR regions, process bounded streams, and export browser deployment manifests.
815
+ - **Corpus risk indicators**: Measure k-anonymity for user-selected quasi-identifiers.
816
+ - **Supply-chain improvements**: Pin model revisions, publish through PyPI Trusted Publishing, and ship standard lockfiles.
817
+ - **Python 3.14**: Added CI coverage alongside Python 3.11 through 3.13.
818
+
819
+ Migration notes:
820
+ - `gliclass_onnx=True` now raises an error because the upstream package has no native ONNX loader.
821
+ - HTML processing now honors `replace_with_html` instead of silently stripping tags.
822
+ - Structured adapters reject reversible mode unless each token map can be retained safely.
823
+
693
824
  **v0.6.0**
694
825
  - **PII detection mode** (`ner_mode='pii'`): auto-configures GLiNER with 60+ PII entity labels (personal, financial, healthcare, identity, digital)
695
826
  - **Synthetic replacement** (`replacement_mode='synthetic'`): Faker-generated realistic values instead of `<TAG>` placeholders, with per-document consistency
@@ -5,11 +5,23 @@ setup.py
5
5
  SqueakyCleanText.egg-info/PKG-INFO
6
6
  SqueakyCleanText.egg-info/SOURCES.txt
7
7
  SqueakyCleanText.egg-info/dependency_links.txt
8
+ SqueakyCleanText.egg-info/entry_points.txt
8
9
  SqueakyCleanText.egg-info/requires.txt
9
10
  SqueakyCleanText.egg-info/top_level.txt
10
11
  sct/__init__.py
12
+ sct/adapters.py
13
+ sct/browser.py
14
+ sct/cli.py
11
15
  sct/config.py
16
+ sct/evaluation.py
17
+ sct/mcp_server.py
18
+ sct/model_benchmark.py
19
+ sct/model_candidates.py
20
+ sct/ocr.py
21
+ sct/privacy.py
22
+ sct/risk.py
12
23
  sct/sct.py
24
+ sct/streaming.py
13
25
  sct/utils/__init__.py
14
26
  sct/utils/anonymization_map.py
15
27
  sct/utils/constants.py
@@ -26,5 +38,16 @@ sct/utils/special.py
26
38
  sct/utils/stopwords.py
27
39
  sct/utils/synthetic.py
28
40
  sct/utils/torch_pipeline.py
41
+ tests/test_adapters.py
42
+ tests/test_browser.py
43
+ tests/test_cli.py
44
+ tests/test_contracts.py
45
+ tests/test_evaluation.py
29
46
  tests/test_functional.py
30
- tests/test_sct.py
47
+ tests/test_mcp_server.py
48
+ tests/test_model_benchmarks.py
49
+ tests/test_ocr.py
50
+ tests/test_privacy.py
51
+ tests/test_risk.py
52
+ tests/test_sct.py
53
+ tests/test_streaming.py
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ sct-clean = sct.cli:main
3
+ sct-mcp = sct.mcp_server:main
@@ -3,7 +3,6 @@ stop-words>=2025.11.4
3
3
  emoji>=2.14
4
4
  ftfy>=6.3
5
5
  Unidecode>=1.4
6
- beautifulsoup4>=4.14
7
6
  onnxruntime>=1.24.2
8
7
  tokenizers>=0.22.2
9
8
  huggingface-hub>=1.5.0
@@ -20,9 +19,6 @@ gliner2<2.0,>=1.0
20
19
  [classify]
21
20
  gliclass>=0.1.16
22
21
 
23
- [classify-onnx]
24
- onnxruntime>=1.24.2
25
-
26
22
  [dev]
27
23
  hypothesis>=6.130
28
24
  faker>=33.0
@@ -43,6 +39,13 @@ gliner2<2.0,>=1.0
43
39
  [gpu]
44
40
  onnxruntime-gpu>=1.24.2
45
41
 
42
+ [mcp]
43
+ fastmcp>=4.0.5
44
+
45
+ [ocr]
46
+ pillow>=12.3.0
47
+ pytesseract>=0.3.13
48
+
46
49
  [presidio]
47
50
  presidio-analyzer>=2.2.360
48
51