tide2 1.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.
Files changed (89) hide show
  1. tide2-1.1.0/.gitignore +81 -0
  2. tide2-1.1.0/CHANGELOG.md +41 -0
  3. tide2-1.1.0/LICENSE-MIT +21 -0
  4. tide2-1.1.0/PKG-INFO +432 -0
  5. tide2-1.1.0/PUBLISHING.md +232 -0
  6. tide2-1.1.0/README.md +352 -0
  7. tide2-1.1.0/pyproject.toml +350 -0
  8. tide2-1.1.0/src/tide2/__init__.py +12 -0
  9. tide2-1.1.0/src/tide2/_version.py +24 -0
  10. tide2-1.1.0/src/tide2/actors/__init__.py +63 -0
  11. tide2-1.1.0/src/tide2/actors/anonymizer.py +808 -0
  12. tide2-1.1.0/src/tide2/actors/llm_recognizer.py +425 -0
  13. tide2-1.1.0/src/tide2/actors/reassembly.py +98 -0
  14. tide2-1.1.0/src/tide2/actors/recognizer.py +605 -0
  15. tide2-1.1.0/src/tide2/actors/transformer.py +549 -0
  16. tide2-1.1.0/src/tide2/anonymizers/__init__.py +39 -0
  17. tide2-1.1.0/src/tide2/anonymizers/accession_number_hash.py +129 -0
  18. tide2-1.1.0/src/tide2/anonymizers/age_grouping.py +334 -0
  19. tide2-1.1.0/src/tide2/anonymizers/date_jitter.py +476 -0
  20. tide2-1.1.0/src/tide2/anonymizers/faker.py +192 -0
  21. tide2-1.1.0/src/tide2/anonymizers/hips_alphanumeric.py +121 -0
  22. tide2-1.1.0/src/tide2/anonymizers/hips_locations.py +318 -0
  23. tide2-1.1.0/src/tide2/anonymizers/hips_names.py +190 -0
  24. tide2-1.1.0/src/tide2/anonymizers/masking.py +40 -0
  25. tide2-1.1.0/src/tide2/anonymizers/presidio_patches.py +209 -0
  26. tide2-1.1.0/src/tide2/cli/__init__.py +21 -0
  27. tide2-1.1.0/src/tide2/cli/main_visualizer.py +36 -0
  28. tide2-1.1.0/src/tide2/cli/unified_interface.py +1032 -0
  29. tide2-1.1.0/src/tide2/cryptographic/__init__.py +44 -0
  30. tide2-1.1.0/src/tide2/cryptographic/date_jitter.py +218 -0
  31. tide2-1.1.0/src/tide2/cryptographic/fpe_strings.py +394 -0
  32. tide2-1.1.0/src/tide2/cryptographic/keys_utils.py +208 -0
  33. tide2-1.1.0/src/tide2/cryptographic/string_selector.py +105 -0
  34. tide2-1.1.0/src/tide2/recognizers/__init__.py +86 -0
  35. tide2-1.1.0/src/tide2/recognizers/accession_recognizer.py +160 -0
  36. tide2-1.1.0/src/tide2/recognizers/address_recognizer.py +291 -0
  37. tide2-1.1.0/src/tide2/recognizers/base64_image_recognizer.py +144 -0
  38. tide2-1.1.0/src/tide2/recognizers/cached_results_transformers_recognizer.py +216 -0
  39. tide2-1.1.0/src/tide2/recognizers/email_recognizer.py +104 -0
  40. tide2-1.1.0/src/tide2/recognizers/genetic_sequence_recognizer.py +183 -0
  41. tide2-1.1.0/src/tide2/recognizers/har_recognizer.py +55 -0
  42. tide2-1.1.0/src/tide2/recognizers/known_values.py +646 -0
  43. tide2-1.1.0/src/tide2/recognizers/llm_json_recognizer.py +553 -0
  44. tide2-1.1.0/src/tide2/recognizers/mrn_recognizer.py +78 -0
  45. tide2-1.1.0/src/tide2/recognizers/passthrough_recognizer.py +77 -0
  46. tide2-1.1.0/src/tide2/recognizers/phone_recognizer.py +130 -0
  47. tide2-1.1.0/src/tide2/recognizers/ssn_recognizer.py +215 -0
  48. tide2-1.1.0/src/tide2/recognizers/transformers_recognizer.py +338 -0
  49. tide2-1.1.0/src/tide2/recognizers/url_recognizer.py +173 -0
  50. tide2-1.1.0/src/tide2/resources/__init__.py +0 -0
  51. tide2-1.1.0/src/tide2/resources/bert_transformer_configuration.json +247 -0
  52. tide2-1.1.0/src/tide2/resources/cities.tsv +43912 -0
  53. tide2-1.1.0/src/tide2/resources/countries.tsv +243 -0
  54. tide2-1.1.0/src/tide2/resources/first_names_with_sex.tsv +34317 -0
  55. tide2-1.1.0/src/tide2/resources/hospitals.txt +567 -0
  56. tide2-1.1.0/src/tide2/resources/llm_prompts/__init__.py +0 -0
  57. tide2-1.1.0/src/tide2/resources/llm_prompts/phi_detection.json +4 -0
  58. tide2-1.1.0/src/tide2/resources/llm_prompts/phi_detection.txt +233 -0
  59. tide2-1.1.0/src/tide2/resources/runner_config_example.yaml +96 -0
  60. tide2-1.1.0/src/tide2/resources/states.tsv +52 -0
  61. tide2-1.1.0/src/tide2/resources/stopwords.txt +418 -0
  62. tide2-1.1.0/src/tide2/resources/street_names.tsv +51543 -0
  63. tide2-1.1.0/src/tide2/resources/surnames.tsv +260174 -0
  64. tide2-1.1.0/src/tide2/resources/unified_names.tsv +2276 -0
  65. tide2-1.1.0/src/tide2/resources/zipcodes.tsv +33121 -0
  66. tide2-1.1.0/src/tide2/runner/__init__.py +62 -0
  67. tide2-1.1.0/src/tide2/runner/cli.py +526 -0
  68. tide2-1.1.0/src/tide2/runner/fault_tolerance.py +280 -0
  69. tide2-1.1.0/src/tide2/runner/local_runner.py +1727 -0
  70. tide2-1.1.0/src/tide2/runner/transformer.py +280 -0
  71. tide2-1.1.0/src/tide2/runner/utils.py +166 -0
  72. tide2-1.1.0/src/tide2/string_parsers/__init__.py +34 -0
  73. tide2-1.1.0/src/tide2/string_parsers/address_parsers.py +519 -0
  74. tide2-1.1.0/src/tide2/string_parsers/format_detector.py +745 -0
  75. tide2-1.1.0/src/tide2/string_parsers/name_parsers.py +297 -0
  76. tide2-1.1.0/src/tide2/string_parsers/name_tokenizer.py +214 -0
  77. tide2-1.1.0/src/tide2/transformers/__init__.py +32 -0
  78. tide2-1.1.0/src/tide2/transformers/config.py +57 -0
  79. tide2-1.1.0/src/tide2/transformers/core.py +546 -0
  80. tide2-1.1.0/src/tide2/utils/__init__.py +13 -0
  81. tide2-1.1.0/src/tide2/utils/batch_columns.py +42 -0
  82. tide2-1.1.0/src/tide2/utils/constants.py +219 -0
  83. tide2-1.1.0/src/tide2/utils/gcs_connector.py +826 -0
  84. tide2-1.1.0/src/tide2/utils/gcs_resource_manager.py +394 -0
  85. tide2-1.1.0/src/tide2/utils/llm_model.py +491 -0
  86. tide2-1.1.0/src/tide2/utils/resource_utils.py +219 -0
  87. tide2-1.1.0/src/tide2/utils/serialization.py +222 -0
  88. tide2-1.1.0/src/tide2/utils/span_metrics.py +1165 -0
  89. tide2-1.1.0/src/tide2/utils/text_processing.py +652 -0
tide2-1.1.0/.gitignore ADDED
@@ -0,0 +1,81 @@
1
+ # Python
2
+ __pycache__/
3
+ *.egg-info/
4
+ tide2.egg-info/
5
+ dist/
6
+ build/
7
+
8
+ # Virtual environments
9
+ .venv/
10
+
11
+ # Buildx cache
12
+ .buildx-cache/
13
+ .buildx-cache-cpu/
14
+ .buildx-cache-gpu/
15
+
16
+ # Testing & coverage
17
+ .pytest_cache/
18
+ .coverage
19
+ htmlcov/
20
+ coverage.xml
21
+
22
+ # IDE & OS
23
+ .DS_Store
24
+ .ipynb_checkpoints/
25
+
26
+ # Environment & secrets
27
+ .env
28
+ .env.local
29
+ keys/
30
+
31
+ # IDE
32
+ .vscode/
33
+
34
+ # Logs
35
+ *.log
36
+ logs/
37
+
38
+ # Local data & temp files
39
+ data/
40
+ local/
41
+ tmp/
42
+
43
+ # Cryptographic key material
44
+ notebooks/sample_data/pipeline_output/salt.bin
45
+ notebooks/sample_data/pipeline_output/key.bin
46
+
47
+ # Coverage artifacts (regenerate in CI)
48
+ coverage-badge.svg
49
+ coverage.xml
50
+
51
+ # Project-specific sample data & outputs
52
+ notebooks/sample_data/sample_output/*
53
+ notebooks/sample_data/sample_output_multi_gpu/*
54
+ notebooks/sample_data/multi_gpu_output/*
55
+ notebooks/sample_data/output_ray/*
56
+ notebooks/sample_data/stanford/*
57
+ notebooks/sample_data/aimi_v1_output/*
58
+ notebooks/sample_data/biomodern_bert_output/*
59
+ notebooks/sample_data_i2b2/*
60
+ notebooks/evaluation/phi_evaluation_results_files/*
61
+ examples/
62
+ notebooks/sample_data/pipeline_output
63
+ notebooks/sample_data/pipeline_output_mac_test
64
+ notebooks/sample_data/pipeline_output_cpu_test
65
+
66
+ # Docs (generated)
67
+ docs/
68
+
69
+ # Test fixtures
70
+ tests/cluster/fixtures/create_fixtures.py
71
+ tests/cluster/smoke_test/*
72
+
73
+ # Misc
74
+ TODO.md
75
+
76
+ /model/**
77
+
78
+ # Versioning is automatically handled
79
+ src/tide2/_version.py
80
+
81
+ temp/**
@@ -0,0 +1,41 @@
1
+ # CHANGELOG
2
+
3
+ <!-- version list -->
4
+
5
+ ## v1.0.0 (2026-06-12)
6
+
7
+ _This release is published under the MIT License._
8
+
9
+ ### Bug Fixes
10
+
11
+ - Fetch base SHA before pre-commit diff on PRs
12
+ ([#14](https://github.com/susom/tide2-core/pull/14),
13
+ [`3a4e4d2`](https://github.com/susom/tide2-core/commit/3a4e4d23da60ae120beb5aa40f44ab9b8738455d))
14
+
15
+ - **anonymizer**: Resolve patient_uid name collision causing silent 0-row output
16
+ ([`34e0619`](https://github.com/susom/tide2-core/commit/34e0619c1644f8fbf7b895482d993bd2dbf32c59))
17
+
18
+ ### Documentation
19
+
20
+ - Correct README and runner docstrings to match code
21
+ ([`f4b09b3`](https://github.com/susom/tide2-core/commit/f4b09b35655d80cc68d6cbe5b878b0e47ede2644))
22
+
23
+ - Remove pre-release private/do-not-publish notice
24
+ ([`fabef8f`](https://github.com/susom/tide2-core/commit/fabef8f4d6cbcb405b7351fb8e20b5ba752416e1))
25
+
26
+ - Update clone URL and venv path to tide2-core
27
+ ([`d440c40`](https://github.com/susom/tide2-core/commit/d440c40719afafb93f821e70739de574c651a677))
28
+
29
+ ### Features
30
+
31
+ - Add OSSF Scorecard support (score 9.1/10)
32
+ ([#11](https://github.com/susom/tide2-core/pull/11),
33
+ [`6ff5249`](https://github.com/susom/tide2-core/commit/6ff5249dc8c0f7bcef803089d36f70a12d6bae87))
34
+
35
+ - Add tide2-core PHI de-identification pipeline
36
+ ([`f165b26`](https://github.com/susom/tide2-core/commit/f165b26bbd849c2eb4a13c3cd5ffd884cad15530))
37
+
38
+ ### Performance Improvements
39
+
40
+ - **pipeline**: Auto-tune CPU resource allocation for Mac/CPU runs
41
+ ([`c96ec32`](https://github.com/susom/tide2-core/commit/c96ec32b1ee614c5d90550743355a604eed3260d))
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 TIDE 2.0 Team
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.
tide2-1.1.0/PKG-INFO ADDED
@@ -0,0 +1,432 @@
1
+ Metadata-Version: 2.4
2
+ Name: tide2
3
+ Version: 1.1.0
4
+ Summary: An advanced data de-identification and anonymization toolkit combining multiple strategies with cryptographic techniques and ML-based entity recognition
5
+ Project-URL: Homepage, https://github.com/susom/tide2-core
6
+ Project-URL: Repository, https://github.com/susom/tide2-core
7
+ Project-URL: Issues, https://github.com/susom/tide2-core/issues
8
+ Project-URL: Documentation, https://susom.github.io/tide2-core/
9
+ Author: TIDE 2.0 Team
10
+ License-Expression: MIT
11
+ License-File: LICENSE-MIT
12
+ Keywords: anonymization,data-protection,de-identification,healthcare,nlp,pii,presidio,privacy
13
+ Classifier: Development Status :: 3 - Alpha
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Intended Audience :: Healthcare Industry
16
+ Classifier: Intended Audience :: Science/Research
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
20
+ Classifier: Topic :: Security :: Cryptography
21
+ Classifier: Topic :: Text Processing :: Linguistic
22
+ Requires-Python: <3.13,>=3.12
23
+ Requires-Dist: aiohttp>=3.14.0
24
+ Requires-Dist: db-dtypes
25
+ Requires-Dist: faker
26
+ Requires-Dist: ff3
27
+ Requires-Dist: google-cloud-bigquery
28
+ Requires-Dist: google-cloud-storage
29
+ Requires-Dist: httpx>=0.25.0
30
+ Requires-Dist: intervaltree>=3.1.0
31
+ Requires-Dist: numpy
32
+ Requires-Dist: orjson>=3.10.0
33
+ Requires-Dist: pandas
34
+ Requires-Dist: presidio-analyzer
35
+ Requires-Dist: presidio-anonymizer
36
+ Requires-Dist: psutil
37
+ Requires-Dist: pyahocorasick
38
+ Requires-Dist: pyarrow>=14.0
39
+ Requires-Dist: pyyaml>=6.0
40
+ Requires-Dist: ray[data,default]>=2.54.0
41
+ Requires-Dist: spacy>=3.8.0
42
+ Requires-Dist: starlette>=1.0.1
43
+ Requires-Dist: streamlit
44
+ Requires-Dist: tenacity
45
+ Requires-Dist: torch
46
+ Requires-Dist: transformers>=5.0.0
47
+ Requires-Dist: usaddress
48
+ Provides-Extra: dev
49
+ Requires-Dist: cython; extra == 'dev'
50
+ Requires-Dist: ipykernel; extra == 'dev'
51
+ Requires-Dist: jupyter; extra == 'dev'
52
+ Requires-Dist: keyring>=25.6.0; extra == 'dev'
53
+ Requires-Dist: keyrings-google-artifactregistry-auth>=1.1.2; extra == 'dev'
54
+ Requires-Dist: pandas-stubs>=2.3.2.250926; extra == 'dev'
55
+ Requires-Dist: pre-commit>=3.5.0; extra == 'dev'
56
+ Requires-Dist: pytest-cov>=4.1.0; extra == 'dev'
57
+ Requires-Dist: pytest>=7.4.0; extra == 'dev'
58
+ Requires-Dist: python-semantic-release>=10.5.3; extra == 'dev'
59
+ Requires-Dist: ruff>=0.1.0; extra == 'dev'
60
+ Requires-Dist: scikit-learn>=1.8.0; extra == 'dev'
61
+ Requires-Dist: scipy>=1.12.0; extra == 'dev'
62
+ Requires-Dist: tqdm>=4.67.1; extra == 'dev'
63
+ Requires-Dist: ty>=0.0.28; extra == 'dev'
64
+ Requires-Dist: types-tqdm>=4.67.0.20250809; extra == 'dev'
65
+ Provides-Extra: docs
66
+ Requires-Dist: pdoc>=14.0; extra == 'docs'
67
+ Provides-Extra: evaluation
68
+ Requires-Dist: scikit-learn>=1.8.0; extra == 'evaluation'
69
+ Requires-Dist: scipy>=1.12.0; extra == 'evaluation'
70
+ Requires-Dist: tqdm>=4.67.1; extra == 'evaluation'
71
+ Provides-Extra: llm
72
+ Requires-Dist: anthropic; extra == 'llm'
73
+ Requires-Dist: google-cloud-aiplatform; extra == 'llm'
74
+ Requires-Dist: google-genai; extra == 'llm'
75
+ Requires-Dist: openai; extra == 'llm'
76
+ Provides-Extra: test
77
+ Requires-Dist: pytest-cov>=4.1.0; extra == 'test'
78
+ Requires-Dist: pytest>=7.4.0; extra == 'test'
79
+ Description-Content-Type: text/markdown
80
+
81
+ # TIDE 2.0
82
+
83
+ A data de-identification and anonymization toolkit that combines multiple anonymization strategies with cryptographic techniques and machine learning-based entity recognition.
84
+
85
+ ## Get Started
86
+
87
+ ### Dev Container (recommended)
88
+
89
+ The repository includes a [Dev Container](https://containers.dev/) configuration that sets up
90
+ the full development environment automatically: Python 3.12, `uv`, all dependencies (including
91
+ GPU group), pre-commit hooks.
92
+
93
+ **Prerequisites:**
94
+ - [Docker](https://docs.docker.com/get-docker/)
95
+ - [VS Code](https://code.visualstudio.com/) with the [Dev Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers)
96
+
97
+ **Steps:**
98
+
99
+ 1. Clone the repository and open it in VS Code:
100
+ ```bash
101
+ git clone https://github.com/susom/tide2-core.git
102
+ cd tide2
103
+ ```
104
+ 2. When VS Code detects `.devcontainer/devcontainer.json`, click **Reopen in Container**
105
+ (or run the command **Dev Containers: Reopen in Container** from the command palette).
106
+ 3. The virtual environment at `/opt/tide2-core/.venv` is activated by default in all terminals.
107
+
108
+ The Dev Container includes these VS Code extensions pre-installed: Python, Ruff, Jupyter,
109
+ Docker, and TOML support.
110
+
111
+ ### Local Installation (without Dev Container)
112
+
113
+ If you prefer to develop outside the Dev Container:
114
+
115
+ ```bash
116
+ # Install uv (https://docs.astral.sh/uv/getting-started/installation/)
117
+ # macOS and Linux
118
+ curl -LsSf https://astral.sh/uv/install.sh | sh
119
+
120
+ # Clone and install
121
+ git clone https://github.com/susom/tide2.git
122
+ cd tide2
123
+
124
+ uv python install 3.12.8
125
+ uv sync
126
+
127
+ # Activate the virtual environment before running any Python commands
128
+ source .venv/bin/activate # macOS / Linux
129
+ # .venv\Scripts\activate # Windows (PowerShell)
130
+ ```
131
+
132
+ ### Quick Start: Interactive Tutorial
133
+
134
+ The tutorial notebook walks you through the de-identification pipeline step by step.
135
+
136
+ **In the Dev Container (or local VS Code):**
137
+
138
+ 1. Open `notebooks/tide2_pipeline.ipynb` (the Jupyter extension is pre-installed in the Dev Container)
139
+ 2. When prompted for a kernel, select the `.venv (Python 3.12)` environment
140
+
141
+ **Jupyter in the browser (local installation):**
142
+
143
+ ```bash
144
+ uv sync --group dev # Install Jupyter (dev dependency group)
145
+ source .venv/bin/activate
146
+ jupyter notebook notebooks/tide2_pipeline.ipynb
147
+ ```
148
+
149
+ View the notebook on GitHub: [TIDE 2.0 Pipeline Tutorial](https://github.com/susom/tide2/blob/main/notebooks/tide2_pipeline.ipynb)
150
+
151
+ **Troubleshooting:**
152
+ - **Run from the repo root** — launch Jupyter from the `tide2/` directory so that relative paths resolve correctly.
153
+ - **GCP credentials are not required** — the notebook downloads the transformer model from HuggingFace Hub by default. Set `project_id` and `bucket_name` in the Configuration cell only if you want to use GCS-hosted weights.
154
+ - **Kernel crashes** — if the Jupyter kernel crashes repeatedly, restart Jupyter (`Ctrl+C`, then re-launch) and run the cells from the top.
155
+
156
+ ### Visualizer Preview
157
+
158
+ TIDE 2.0 includes a Streamlit visualizer for comparing original and de-identified text side by side:
159
+
160
+ ![TIDE 2.0 Visualizer](notebooks/images/visualizer_screenshot.png)
161
+
162
+ Launch it with:
163
+ ```bash
164
+ tide2-visualizer
165
+ ```
166
+
167
+ To stop the visualizer, press `Ctrl+C` in the terminal (works on macOS, Linux, and Windows).
168
+
169
+ ---
170
+
171
+ ## Overview
172
+
173
+ TIDE 2.0 is a Python package for anonymizing sensitive data in healthcare and research contexts. It identifies and anonymizes personally identifiable information (PII) while maintaining data utility for analysis and research.
174
+
175
+ ## Features
176
+
177
+ ### Entity Recognition
178
+ - **Transformer-based NER**: HuggingFace transformer models with direct batch inference (bypasses HF pipeline), BIO token aggregation, and chunk-to-document reassembly
179
+ - **Regex recognizers**: Phone, URL/IP, Email, SSN, Address — replacements for Presidio defaults (10-100x faster)
180
+ - **Healthcare-specific**: MRN, Accession Number, HAR code recognizers
181
+ - **Known values detection**: Aho-Corasick based matching against patient databases
182
+ - **Specialized**: Base64 image detection, genetic sequence detection, LLM-based JSON recognizer
183
+ - **Cached results**: Pre-computed NER results from GPU batch processing via `CachedResultsTransformerRecognizer`
184
+ - **Presidio Integration**: Built on Microsoft's Presidio framework
185
+
186
+ ### Anonymization Strategies
187
+ - **HIPS (Healthcare Identity Protection System)**: Cryptographic deterministic anonymization for names, locations, and alphanumeric identifiers
188
+ - **Accession number hashing**: SHA256-based, compatible with BigQuery UDF
189
+ - **Faker Integration**: Realistic fake data generation
190
+ - **Date Jittering**: Deterministic, privacy-preserving date shifts derived from patient keys
191
+ - **Age Grouping**: Age range categorization
192
+
193
+ ### Cryptographic Protection
194
+ - **Format-Preserving Encryption (FPE)**: Maintains data format during encryption
195
+ - **Key Management**: Key generation, storage, and derivation utilities
196
+ - **Deterministic date jitter**: Batch-capable date shift derivation from cryptographic keys
197
+ - **String Selection**: HMAC-based cached string selection
198
+
199
+ ### Ray-based Batch Processing
200
+ - **Runner module**: Single-node job runner with local and VM modes via `tide2-runner` CLI
201
+ - **Ray actors**: `RecognizerActor`, `AnonymizerActor`, `TransformerInferenceActor`, `BIOAggregationActor`, `ReassemblyActor` for `ray.data.map_batches`
202
+ - **Two-stage GPU/CPU pipeline**: GPU inference returns raw BIO tokens; CPU actors aggregate them concurrently via Ray Data streaming
203
+ - **Direct inference**: Bypasses HuggingFace pipeline dispatch loop with batch tokenize → single GPU forward pass → offset-based extraction
204
+ - **Adaptive GPU batching**: Auto-computes batch size from model config and free GPU memory; adjusts based on text lengths with VRAM-aware budgets (override via `--short-seq-budget`)
205
+ - **OOM recovery**: Automatic batch splitting on CUDA out-of-memory errors
206
+ - **Fault tolerance**: Actor restarts, task retries, graceful shutdown
207
+ - **YAML config**: All CLI arguments can be specified in a YAML config file (`--config`)
208
+
209
+ ### Utilities
210
+ - **Text processing**: Text chunking, BIO aggregation, span reconstruction, deduplication
211
+ - **String parsers**: Name parsing/classification, address parsing, format detection
212
+ - **Span metrics**: Gold vs ML evaluation, O(n log n) conflict resolution
213
+ - **GCS cache**: Auto-download models from GCS to `~/.cache/tide2/`
214
+ - **Model compilation**: `torch.compile` with mega-cache support for faster inference startup
215
+
216
+ ### Command Line Tools
217
+ - **`tide2-runner`**: Ray-based single-node job runner with six job types: `recognizer`, `anonymizer`, `transformer`, `reassembly`, `pipeline` (full end-to-end), and `llm-recognizer`. Supports YAML config files (`--config`) and dry-run mode (`--dry-run`).
218
+ - **`tide2-visualizer`**: Streamlit app for side-by-side PHI comparison and entity editing.
219
+
220
+
221
+ ### Cloud Integration
222
+ - **GCS**: input/output I/O and model caching.
223
+ - **BigQuery**: input/output of notes and recognizer/anonymizer results (e.g. via `ARRAY_AGG`-grouped chunk columns) for the runner and visualizer.
224
+ - **Automatic Caching**: Download and cache models from GCS automatically (`$TIDE_CACHE_DIR`).
225
+
226
+ ## CLI Usage
227
+
228
+ ### Runner CLI (Ray-based processing)
229
+
230
+ ```bash
231
+ # Run recognition locally
232
+ tide2-runner run recognizer -i ./data/input -o ./data/output
233
+
234
+ # Run with more resources (e.g. on a large VM), reading/writing from GCS
235
+ tide2-runner run recognizer -i gs://bucket/input -o gs://bucket/output \
236
+ --num-cpus 224 --num-actors 200
237
+
238
+ # Run transformer NER on GPU
239
+ tide2-runner run transformer -i ./data/input -o ./data/transformer_output \
240
+ --model StanfordAIMI/stanford-deidentifier-v2 --batch-size 2048
241
+
242
+ # Run transformer with YAML config
243
+ tide2-runner run transformer --config config.yaml
244
+
245
+ # Run the full pipeline (transformer -> recognizer -> anonymizer)
246
+ tide2-runner run pipeline -i ./data/input.parquet -o ./data/output \
247
+ --model StanfordAIMI/stanford-deidentifier-v2
248
+
249
+ # If you are running on Mac, you can use --object-store-gb option to set
250
+ tide2-runner run pipeline -i ./data/input.parquet -o ./data/output \
251
+ --model StanfordAIMI/stanford-deidentifier-v2 --object-store-gb 2
252
+
253
+ # Run anonymization
254
+ tide2-runner run anonymizer -i ./data/recognized -o ./data/anonymized \
255
+ --salt /path/to/salt.bin --key /path/to/key.bin
256
+ ```
257
+
258
+
259
+ ### Interactive Visualizer
260
+
261
+ ```bash
262
+ # Launch the Streamlit PHI visualizer
263
+ tide2-visualizer
264
+ ```
265
+
266
+ ## Docker Images
267
+
268
+ Several targets are built from a single multi-stage `Dockerfile`:
269
+
270
+ - `production-cpu` — slim CPU-only image (no CUDA, no `gpu` dependency group). Used by recognizer, anonymizer, and BigQuery tasks.
271
+ - `production-gpu` — GPU image based on `nvidia/cuda:13.0.2-cudnn-runtime-ubuntu24.04`, includes the `gpu` dependency group (`torch`, `transformers`, `spacy`). Used by transformer inference.
272
+ - `development` — Dev Container target with `git`, `gcloud`, build tools, and the full dev environment.
273
+ - `test` — extends `development` and runs the test suite (used by `make test-docker`).
274
+
275
+ Build and push the GPU image (requires `DOCKER_REGISTRY` and `DOCKER_IMAGE_GPU` in `.env`):
276
+
277
+ ```bash
278
+ make docker # build + push the GPU image (alias for docker-gpu)
279
+ make docker-gpu # build + push the GPU image
280
+ make test-docker # build the test target and run the suite in Docker
281
+ ```
282
+
283
+ ## Dependency Groups
284
+
285
+ - **`llm`**: LLM provider SDKs for the optional LLM-based recognizer (`anthropic`, `openai`, `google-genai`, `google-cloud-aiplatform`)
286
+ - **`dev`**: Development tools (`pytest`, `pytest-cov`, `ty`, `ruff`, `pre-commit`), Jupyter, and the `evaluation` libraries (`scikit-learn`, `scipy`, `tqdm`)
287
+ - **`evaluation`**: Evaluation/analysis libraries (`scikit-learn`, `scipy`, `tqdm`)
288
+ - **`test`**: Minimal test dependencies (`pytest`, `pytest-cov`)
289
+ - **`docs`**: API documentation generation (`pdoc`)
290
+
291
+ Install an optional group as an extra with `uv sync --extra <name>`, or all extras with `uv sync --all-extras`. (These same sets are also defined as `[dependency-groups]`, usable with `uv sync --group <name>`.)
292
+
293
+ Note: The full ML inference stack (`torch`, `transformers`, `spacy`) ships in the main package by default — it is required, since no model can run without it. The `llm` extra is only needed for the optional LLM-based recognizer.
294
+
295
+ ## Architecture
296
+
297
+ ```
298
+ tide2/
299
+ ├── recognizers/ # PII detection (Presidio EntityRecognizer subclasses)
300
+ ├── anonymizers/ # PII replacement (Presidio Operator subclasses)
301
+ ├── transformers/ # Core NER inference engine (TransformerCore)
302
+ │ ├── core.py # Model loading, direct inference, BIO aggregation
303
+ │ └── config.py # Model configuration management
304
+ ├── actors/ # Ray actors for distributed batch processing
305
+ │ ├── transformer.py # GPU inference actor + CPU BIO aggregation actor
306
+ │ ├── recognizer.py # CPU recognizer actor
307
+ │ ├── anonymizer.py # CPU anonymizer actor
308
+ │ ├── reassembly.py # Chunk-to-document reassembly actor
309
+ │ └── llm_recognizer.py # LLM-based recognizer actor
310
+ ├── cryptographic/ # FPE, key management, date jitter derivation
311
+ ├── string_parsers/ # Name/address parsing, format detection
312
+ ├── runner/ # Ray-based single-node job runner + CLI
313
+ │ ├── local_runner.py # LocalJobRunner: transformer/recognizer/anonymizer/reassembly/pipeline/llm
314
+ │ ├── cli.py # tide2-runner CLI with YAML config support
315
+ │ ├── transformer.py # Document chunking and reassembly logic
316
+ │ ├── fault_tolerance.py # Actor restarts, graceful shutdown
317
+ │ └── utils.py # Runner utilities
318
+ ├── cli/ # Streamlit visualizer
319
+ ├── utils/
320
+ │ ├── gcs_resource_manager.py # GCS auto-download and caching
321
+ │ ├── gcs_connector.py # GCS file I/O
322
+ │ ├── span_metrics.py # Evaluation metrics and conflict resolution
323
+ │ ├── text_processing.py # Chunking, BIO aggregation, span reconstruction
324
+ │ ├── serialization.py # RecognizerResult <-> dict conversions
325
+ │ ├── llm_model.py # LLM client utilities
326
+ │ ├── batch_columns.py # Batch column constants
327
+ │ ├── constants.py # Shared constants
328
+ │ └── resource_utils.py # Resource path helpers
329
+ └── resources/ # Config files (model configs, name lists, etc.)
330
+ ```
331
+
332
+ ## Testing
333
+
334
+ ```bash
335
+ # Run all unit tests (coverage report prints automatically)
336
+ uv run pytest
337
+
338
+ # Run without coverage (faster, useful when debugging)
339
+ uv run pytest --no-cov
340
+
341
+ # Run a specific test file
342
+ uv run pytest tests/test_masking_anonymizer.py
343
+
344
+ # Skip slow integration tests
345
+ uv run pytest -m "not integration"
346
+ ```
347
+
348
+ Coverage is configured in `pyproject.toml` and runs automatically with `pytest`. Three reports are generated on each run:
349
+
350
+ - **Terminal**: line-by-line missing coverage printed to stdout
351
+ - **HTML**: detailed report at `htmlcov/index.html`
352
+ - **XML**: `coverage.xml` (Cobertura format)
353
+
354
+ ## Documentation
355
+
356
+ ### API Reference
357
+
358
+ API documentation is hosted via GitHub Pages: [https://susom.github.io/tide2/](https://susom.github.io/tide2/)
359
+
360
+ To build or preview docs locally (generated with [pdoc](https://pdoc.dev/)):
361
+
362
+ ```bash
363
+ # Install docs dependencies (pdoc); the ML stack ships in the base install,
364
+ # so all modules import without an extra
365
+ uv sync --extra docs
366
+
367
+ # Live preview (opens a local server with hot reload)
368
+ make docs-serve
369
+
370
+ # Generate static HTML to docs/
371
+ make docs
372
+ ```
373
+
374
+ Deployment to GitHub Pages is automated: the [`.github/workflows/docs.yml`](.github/workflows/docs.yml)
375
+ workflow runs `make docs` on every push to `main` and publishes the `docs/` directory as a
376
+ Pages artifact.
377
+
378
+ ### Other Resources
379
+
380
+ - **Examples**: Check the `notebooks/` directory for usage examples
381
+ - **Tests**: Test suite in `tests/` directory
382
+
383
+ ## Requirements
384
+
385
+ - **Dev Container**: Recommended — provides the full environment with no manual setup (requires Docker and VS Code with the Dev Containers extension)
386
+ - **Python**: 3.12 (required, `>=3.12,<3.13`) — constrained to 3.12 for compatibility with the `spacy`/`thinc` C-extension stack and other pinned dependencies.
387
+ - **Package Manager**: uv (not pip or poetry)
388
+ - **Virtual Environment**: `.venv/` (activated automatically in the Dev Container; must be activated manually for local installs)
389
+ - **Core Dependencies**: Presidio, Ray (`>=2.54`), Cryptography, Faker, Google Cloud libraries, and the ML inference stack (`torch`, `transformers>=5.0`, `spacy`) — all required and shipped in the base install
390
+
391
+ ## Security Considerations
392
+
393
+ - Cryptographic operations use standard libraries (cryptography, pyca/cryptography)
394
+ - Format-preserving encryption maintains data format during encryption
395
+ - Key management supports generation, storage, and rotation
396
+ - Anonymization strategies are designed to prevent re-identification
397
+
398
+ ## Contributing
399
+
400
+ Please see [CONTRIBUTING.md](CONTRIBUTING.md) for the development workflow, branching
401
+ model, commit-message conventions, and the pull request checklist. The
402
+ [Dev Container setup](#dev-container-recommended) above provisions the full
403
+ development environment (including pre-commit hooks) automatically.
404
+
405
+ ## License
406
+
407
+ This project is licensed under the MIT License - see the [LICENSE-MIT](LICENSE-MIT) file for details.
408
+
409
+ ## Citation
410
+
411
+ If you use TIDE 2.0 in your research, please cite:
412
+
413
+ ```bibtex
414
+ @software{tide2,
415
+ title={TIDE 2.0: Data De-identification and Anonymization Toolkit},
416
+ author={TIDE 2.0 Team},
417
+ year={2025},
418
+ url={https://github.com/susom/tide2}
419
+ }
420
+ ```
421
+
422
+ ## Support
423
+
424
+ - **Issues**: [GitHub Issues](https://github.com/susom/tide2/issues)
425
+ - **Discussions**: [GitHub Discussions](https://github.com/susom/tide2/discussions)
426
+ - **Development**: See the Contributing section above
427
+
428
+ ---
429
+
430
+ **Synthetic Data Notice**: All sample data included in this repository (under `notebooks/sample_data/`) is entirely synthetic and fabricated. No real patient data is included. See [`notebooks/sample_data/README.md`](notebooks/sample_data/README.md) for details.
431
+
432
+ **Note**: This toolkit is designed for research and development purposes. Please ensure compliance with relevant privacy laws and regulations (HIPAA, GDPR, etc.) when using in production environments.