Offsets you can check
A span is a slice of your string, not a sentence a model rewrote. You can assert it in a test and diff it in a review.
Python library · Apache-2.0 · local weights
edgepii finds personally identifiable information as typed character spans on the
string you passed in. Every result row proves one thing:
source[start:end] == text. If a detector returns an offset that fails that check,
the library drops the span and counts it. It never searches the string for a repair.
Real output from the rules lane. No weights, no network.
Source
Masked
Customer Ada Lovelace called from <PHONE_1>. Email <EMAIL_1>. Card <PAYMENT_1>. Order 48291.
Span table
| Type | Start | End | Text | Score |
|---|---|---|---|---|
| PHONE | 34 | 48 | +852 5555 0101 | — |
| 56 | 71 | ada@example.com | — | |
| PAYMENT | 78 | 94 | 4242424242424242 | 1.00 |
A dash means no checksum covers that form, so the library reports no score.
It does not invent a probability. Order 48291 stays clear because an internal id is
not in the type list.
A span is a slice of your string, not a sentence a model rewrote. You can assert it in a test and diff it in a review.
Email, phone, card, IBAN, and IP follow a published grammar or checksum. Names need a model. The preset runs both and merges the results.
A password is masked irreversibly and never enters the vault. Restoring it would leak the credential into the next system.
Two pinned corpora with a sha256 each. Exact-span F1 per type, with the misses
counted. See the score.
Three calls: build a locator, locate spans, mask them.
from edgepii import Locator, redact
source = (
"Customer Ada Lovelace called from +852 5555 0101. "
"Email ada@example.com. Card 4242424242424242. Order 48291."
)
result = Locator.preset("rules").locate(source)
for span in result.spans:
proof = source[span.start:span.end] == span.text
print(span.type, span.start, span.end, repr(span.text), proof)
masked, vault = redact(source, result.spans)
print(masked)
# Customer Ada Lovelace called from <PHONE_1>. Email <EMAIL_1>. Card <PAYMENT_1>. Order 48291.
One YAML file is the only type list. Rank breaks an overlap.
SECRETsecretGOV_IDgov_idPAYMENTpaymentADDRESSpersonEMAILcontactIP_ADDRESScontactPERSONpersonPHONEcontactUSERNAMEcontactDATE_OF_BIRTHquasiORGquasi