Personal identifiers¶
pii ¶
Detect and mask Indian PII in Odia text: phone, email, URL, Aadhaar, PAN and PIN code.
Rule-based and offline: patterns plus the Verhoeff checksum for Aadhaar. Person names, street addresses, dates and amounts are not detected, so masking is not anonymisation.
Examples:
>>> from openodia import pii
>>> pii.mask("ମୋ ଫୋନ ୯୮୭୬୫୪୩୨୧୦ ।")
'ମୋ ଫୋନ <PHONE> ।'
PIIEntity
dataclass
¶
One detected span; start and end are character offsets into the original input.
detect ¶
detect(
text: str,
types: Iterable[str] | None = None,
min_confidence: float = 0.0,
) -> list[PIIEntity]
Find PII spans in text, sorted by position and never overlapping.
Odia and ASCII digits are both recognised. types limits the search to some of
PII_TYPES. min_confidence (0 to 1) drops weaker matches first. Matches that
overlap are merged into one entity spanning all of them, so for every detected value no
part of it is left visible; see the limits below. Its type and confidence come from the
longest match; on a tie the earlier of EMAIL, URL, AADHAAR, PAN, PHONE, PINCODE wins.
Limits: an email local part over 64 characters is not found, and one with punctuation keeps its earlier part visible; one that starts with non-ASCII letters keeps those letters visible.
Raises:
| Type | Description |
|---|---|
TypeError
|
|
ValueError
|
|
mask ¶
mask(
text: str,
types: Iterable[str] | None = None,
min_confidence: float = 0.0,
placeholder: Callable[[PIIEntity], str] = _tag,
) -> str
Replace every detected span with placeholder(entity), <TYPE> by default.
Replacing a value can expose a neighbour that was glued to it, such as a PAN written directly
before a URL. So detection and replacement repeat until nothing changes, at most 10 times.
With the default tags the result is stable: masking it again changes nothing, unless the input
chains more than 10 such glued values. From the second pass on, placeholder receives
entities whose offsets index the partly masked text. A custom placeholder that returns
text matching a detector can keep the loop going until the limit.
Past 10 glued values the result can still contain raw PII, so do not rely on it for input
that chains that many. types is read once, so an iterator works.