Skip to main content

Allyanonimiser

PyPI version Python Versions Tests Coverage Package License: MIT Documentation

Australian-focused PII detection and anonymization for the insurance industry — fast, regex + spaCy, no GPU. Detects 43 entity types (TFN, Medicare, ABN with checksums; policy/claim numbers; international phone/SSN/credit-card shapes) and anonymizes them with configurable operators, with stream processing for very large files.

📖 Full documentation · Changelog

Version 3.6.0 — Streaming, Configuration and State-Isolation Fixes

  • Streaming works on real CSV files — stream_from_file() crashed on any real file in 3.5.x. It now reads ordered row batches with correct counts and row indices, and writes entity output incrementally.
  • Exported configuration reproduces behaviour — exports now include custom patterns, analyzer settings and priorities, and reload into identical detections in JSON or YAML.
  • Opt-in sensitive-output controls — minimal_output=True drops original values, source columns, caches and reports. require_spacy_model=True fails at start-up instead of silently running without NER.
  • State isolation fixes — cached results can no longer be altered by callers or earlier calls, cache limits are enforced, custom pattern scores are honoured, and duplicate DataFrame index labels keep their own rows' output.
  • Reports belong to their instance — instances no longer share one report. Pass a shared ReportingManager to combine them.
  • Offline detection evaluation — bench/eval_ally.py plus a pattern-only regression gate in the test suite. Detection quality on the AU corpus is unchanged from 3.5.1.

Compatibility: the stream extra needs Polars 1.37 or later, and streaming reads CSV columns as strings by default.

3.5.1 (prior)

  • Per-call options no longer leak — analyze(active_entity_types=...) / min_score_threshold=... are now true per-call parameters instead of sticky setters that silently restricted every later call (also fixed in the DataFrame and stream processors).
  • analyze_batch() now matches analyze() exactly — the batch path previously skipped false-positive filtering, so DataFrame/CSV processing missed the v3.5.0 precision work.
  • Label-context disambiguation — "TFN is 123 456 789" now resolves to AU_TFN instead of the bare 9-digit CRN shape; explicit labels beat shape priority and checksum validation.
  • Span-containment absorption — DATE fragments inside DOB spans, stray NUMBER triplets inside identifiers, and CRN-tail-of-ABN matches are absorbed by their containing span.
  • Fresh-install fix — explicit click>=8.0 dependency shields against the upstream typer 0.26.8 break that made import spacy (and therefore this package) fail in newly resolved environments.

See the changelog for full details and earlier releases.

Installation

pip install allyanonimiser==3.6.0

# With stream processing support for large files (polars + pyarrow)
pip install "allyanonimiser[stream]==3.6.0"

# spaCy model for NER (the library defaults to the small model)
python -m spacy download en_core_web_sm

Requires Python 3.12 or 3.13.

The default en_core_web_sm model (44 MB) suits most pipelines — pattern-based detection (TFN, ABN, Medicare, phones, emails, dates) is identical regardless of model. Install en_core_web_lg (587 MB) and pass spacy_model=SPACY_MODEL_ACCURATE when missing a person's name is a real cost, or spacy_model=None for pattern-only mode. See Installation for the full model tradeoff table.

Quick Start

from allyanonimiser import create_allyanonimiser

# Create the Allyanonimiser instance with default settings
ally = create_allyanonimiser()

# Analyze text
results = ally.analyze(
    text="Please reference your policy AU-12345678 for claims related to your vehicle rego XYZ123."
)

# Print results
for result in results:
    print(f"Entity: {result.entity_type}, Text: {result.text}, Score: {result.score}")

# Anonymize text
anonymized = ally.anonymize(
    text="Please reference your policy AU-12345678 for claims related to your vehicle rego XYZ123.",
    operators={
        "POLICY_NUMBER": "mask",  # Replace with asterisks
        "VEHICLE_REGISTRATION": "replace"  # Replace with <VEHICLE_REGISTRATION>
    }
)

print(anonymized["text"])
# Output: "Please reference your policy ********** for claims related to your vehicle rego <VEHICLE_REGISTRATION>."

Adding Custom Patterns

from allyanonimiser import create_allyanonimiser

ally = create_allyanonimiser()

# Add a custom pattern with regex
ally.add_pattern({
    "entity_type": "REFERENCE_CODE",
    "patterns": [r"REF-\d{6}-[A-Z]{2}", r"Reference\s+#\d{6}"],
    "context": ["reference", "code", "ref"],
    "name": "Reference Code"
})

# Or generate a pattern from examples
ally.create_pattern_from_examples(
    entity_type="EMPLOYEE_ID",
    examples=["EMP00123", "EMP45678", "EMP98765"],
    context=["employee", "staff", "id"],
    generalization_level="medium"  # Options: none, low, medium, high
)

More in the docs: Analyzing Text · Anonymizing Text · Working with DataFrames · Custom Patterns

Features

  • Australian-focused PII: TFN, ABN, ACN (with checksum validation), Medicare, AU phone formats, driver's licenses, addresses with state/postcode anchoring, Centrelink CRN, passport
  • Insurance domain: policy numbers, claim references, vehicle registration, VIN, broker codes, incident dates
  • International shapes (v3.5+): PHONE_INTL, US_SSN, Luhn-validated CREDIT_CARD, ISO_DATETIME, TIME
  • Flexible anonymization: replace, mask, redact, hash (SHA-256), age-bracket operators, postcode preservation within addresses
  • Context-aware resolution: explicit labels ("TFN is …") beat bare-shape matches; overlapping and contained entities resolved by configurable priority
  • Scale: batch analysis via nlp.pipe(), pandas DataFrames with optional PyArrow backing, memory-efficient chunked stream processing via Polars
  • Reporting: session-level statistics, entity histograms, Jupyter-native rendering

43 entity types across five categories — see the pattern catalogue for the complete reference with examples, or Australian and International pattern deep-dives.

Benchmarks

Head-to-head against openai/privacy-filter (a 1.5B-parameter token classifier) with character-level P/R/F1 scoring. On the enriched AU-insurance bench (160 synthetic docs, ~8 PII spans each), Allyanonimiser wins 5 of 6 categories at ~24× the throughput, on CPU, without torch:

Category Allyanonimiser F1 openai/privacy-filter F1
PERSON 0.954 0.908
ADDRESS 0.962 0.940
EMAIL 1.000 0.982
PHONE 1.000 0.870
DATE 0.997 0.964
Account-like IDs (TFN, Medicare, ABN, policy, VIN, …) 0.997 0.880
Overall (any PII) 0.950 0.958

On general multilingual PII (AI4Privacy, 1,000 English rows) the two are tied overall (0.782 vs 0.781); on legal text (TAB/ECHR) Allyanonimiser leads overall (0.560 vs 0.378). Full tables, methodology, and how-to-reproduce: Benchmarks. Eval scripts and synthetic data are in bench/.

Migrating from v2.x

v3.0 restructured the package into layered modules and replaced the stringly-typed management methods with explicit ones. Top-level imports (create_allyanonimiser, EnhancedAnalyzer, DataFrameProcessor, …) are unchanged. See the migration guide.

Documentation

License

MIT — see LICENSE.

Metadata

Release files for allyanonimiser 3.6.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for allyanonimiser 3.6.0
File Size Uploaded Provenance Actions
allyanonimiser-3.6.0.tar.gz 154.8 kB Without provenance Details for allyanonimiser-3.6.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for allyanonimiser 3.6.0
File Interpreter ABI Platform Actions
allyanonimiser-3.6.0-py3-none-any.whl Python 3 none any Details for allyanonimiser-3.6.0-py3-none-any.whl

Total release size: 253.8 kB

Release files / allyanonimiser-3.6.0.tar.gz

Download URL allyanonimiser-3.6.0.tar.gz
Size 154.8 kB
Tags Source
SHA-256 checksum
How to use checksums
31d543bd40d535040d2aec2914665e153889c10993e8520df6ffa67a9292d46c
BLAKE2b-256 checksum
How to use checksums
0db0324644fe1863adeceebd5e629ec54081cf844d60ffc3c8466a6daca896d8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.9

Release files / allyanonimiser-3.6.0-py3-none-any.whl

Download URL allyanonimiser-3.6.0-py3-none-any.whl
Size 99.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b240eac2287124d2f48958393d270a5ecefdf186071e341d1c50250847b0bca8
BLAKE2b-256 checksum
How to use checksums
ee334d4580092f77dc5ccaabd4875b29ffa45535ca7ea9edacad0d2dd2fcacd8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.12.9

Security for allyanonimiser 3.6.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.

Release history Release notifications | RSS feed

This release

3.6.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page