redacta
Pseudonymise patient identifiers and PII in text — and restore them. A local, dependency-free Python pattern engine.
pip install redacta
from redacta import redact, reinstate
redacted, report, token_map = redact(
"Dear patient, NHS Number: 943 476 5919, tel 0113 278 4532."
)
# redacted -> "Dear patient, NHS Number: [NHS_NUMBER_1], tel [PHONE_1]."
original = reinstate(redacted, token_map)
# original -> "Dear patient, NHS Number: 943 476 5919, tel 0113 278 4532."
What it detects
Deterministic, checksum-validated patterns: NHS numbers (Modulus-11), UK National
Insurance numbers, dates of birth (keyword-anchored; appointment dates left
intact by default), UK postcodes, US SSNs and ZIP codes, hospital/MRN numbers,
emails, phone numbers, URLs, IP addresses, Luhn-validated payment cards, IBANs,
account numbers, and UK vehicle registrations — plus keyword-anchored patient,
relative and carer names (clinician names preserved). Same value → same token; a
token_map lets you reverse it.
Names in free prose aren't caught (they need an LLM — see the Redacta agent skill). Stdlib only, no network calls; review output before sharing.
Safe Harbor mode
redacted, report, token_map = redact(text, safe_harbor=True)
Applies the stricter HIPAA Safe Harbor (§164.514) pass on top of the default: all dates (not just DOB — appointment dates included), specific ages, fax numbers, certificate/licence numbers, device serial numbers, VINs, and health-plan/beneficiary numbers. Over-redacts slightly versus the letter of the standard, on the safe side. Not legal advice.
PrivacyGateway — for agent workflows
redact() hands you the token map; in an agent workflow that map is the key to
the whole record, and it shouldn't travel with the text. PrivacyGateway keeps
it inside expiring in-process sessions instead — the same loop the Redacta MCP
server enforces across a process boundary.
from redacta import PrivacyGateway
gateway = PrivacyGateway() # PrivacyGateway(safe_harbor=True) for the strict pass
protected = gateway.protect(clinical_note) # .text, .session_id, .report — no token map
response = my_agent(protected.text) # the agent sees tokens only
guard = gateway.check_output(response, protected.session_id)
# {"safe": bool, "leaks": [{"token", "category"}], "sanitized_text": str}
released = gateway.release(guard["sanitized_text"], protected.session_id)
# .text with originals restored — restoration is an explicit act
Sessions expire (default 1 h, capped at 64, oldest evicted); any failed lookup
raises GatewayError("Unknown or expired session.") — one generic message.
guard_output(text, token_map) is also importable standalone. Honest scope: an
in-process library is discipline, not enforcement — for enforcement against an
untrusted consumer, use the Redacta MCP server, which holds the map in a
separate process.
Self-check
from redacta import self_check
leftovers = self_check(redacted) # [{'label': ..., 'sample': ...}, ...]
CLI
redacta letter.txt # prints JSON: redacted_text, report, token_map
redacta letter.txt --text-only # just the redacted text
redacta letter.txt --safe-harbor # strict HIPAA Safe Harbor pass
redacta-reinstate redacted.txt --map token_map.json
License
MIT-0 (MIT No Attribution). Built by PharmaTools.AI.
Metadata
Release files for redacta 1.4.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| redacta-1.4.0.tar.gz | 18.8 kB | Without provenance | Details for redacta-1.4.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| redacta-1.4.0-py3-none-any.whl | Python 3 | none | any | Details for redacta-1.4.0-py3-none-any.whl |
Total release size: 35.2 kB
Release files / redacta-1.4.0.tar.gz
| Download URL | redacta-1.4.0.tar.gz |
|---|---|
| Size | 18.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f8738212f61e708cc9a37730e0a3aed242a2213c618594cb5efd1fca8232e9df
|
|
BLAKE2b-256 checksum How to use checksums |
d34cbbc998e5ea21494cfa4c06fe16df0a5de03ceca861f0877aff148744007a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|
Release files / redacta-1.4.0-py3-none-any.whl
| Download URL | redacta-1.4.0-py3-none-any.whl |
|---|---|
| Size | 16.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
03c8e389d438b6f902adf87ef75d6eb56c9eb4b279d59d5fd1789d2c15e9c761
|
|
BLAKE2b-256 checksum How to use checksums |
7587f8245f443f49e8eb400184a606a8cc1efa0e2d6a51f343eb9d55a7761284
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|
Security for redacta 1.4.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.