Programmatic API & SDK Reference¶
Developers can integrate pdf-anonymizer-core directly into their Python applications (e.g. data processing pipelines, web apps, or custom AI agent loops).
anonymize_file¶
The anonymize_file function reads, extracts, chunks, and masks a file, returning the final anonymized string and the mapped PII dictionary. For .csv / .xlsx the string is a row-wise review flatten (used by verify/risk), not spreadsheet bytes. For .docx the string is a part-wise flatten of paragraphs, not the Word package.
Import Signature¶
Parameters¶
file_path(str): The absolute or relative path to the input document (supports.pdf,.md,.txt,.csv,.xlsx,.docx). Excel needs the[excel]extra. Word needs the[docx]extra.characters_to_anonymize(int): Target character size of each chunk sent to the LLM.prompt_template(str): The prompt template string containing instructions for entity masking.model_name(str): The target model name (e.g."gemini-2.5-flash","google/gemini-2.5-pro","ollama/phi4-mini").anonymized_entities(list[str], optional): Type filter (e.g.["PERSON", "ORGANIZATION"]). ListingIBANalso includesIBAN_LIKE.regex_patterns(dict, optional): First-stage RE2 map. Defaults toDEFAULT_REGEX_PATTERNS. Usefilter_regex_patterns(["US", "GB"])to keep only some national IDs.operators(dict[str, str], optional): Type →replace/mask/hash/generalize/shift/fake. Unlisted types stayreplace.fake_secret(str, optional): Seed forfake. Same person + type + secret → same fake.seed_mapping(dict[str, str], optional): Original → written map from a previous file so Ada staysPERSON_1.keep_list/deny_list(list[str], optional): Phrases to leave visible, or to force-hide asCUSTOM_n. Keep wins if both lists contain the same phrase.min_confidence(float, optional): Drop spans whose score is below this value. Default0keeps every hit. Not a calibrated probability.use_ner(bool, optional): Run local span NER. SDK defaultFalseso a checkpoint is never downloaded unless you ask.
Returns¶
anonymized_text(str): The fully processed text with placeholders in place of PII. For tables this is the review flatten, not a CSV/Excel dump. For Word this is the part-wise flatten, not.docxbytes.mapping(dict[str, str]): A dictionary mapping original entities to their assigned placeholders (or other written form).
anonymize_tabular_file¶
Use this when you need to write a .csv / .xlsx via save_results. It returns a third value, entity_texts, that save_results requires on the table path.
Import Signature¶
from pdf_anonymizer_core.core import anonymize_tabular_file
from pdf_anonymizer_core.utils import save_results
Returns¶
review(str): Row-wise flatten of the masked table.mapping(dict[str, str]): Original → written, same asanonymize_file.entity_texts(tuple[str, ...]): The sameentity["text"]list the text engine passes toreplace_entities.
review, mapping, entity_texts = anonymize_tabular_file(
"people.csv",
characters_to_anonymize=100000,
prompt_template="",
model_name="",
use_llm=False,
)
# Pass the CLI invert (placeholder → original). Do not pass an orig→written
# mask/hash/fake map (for example {addr: "****"}).
save_results(
review,
{v: k for k, v in mapping.items()},
"people.csv",
entity_texts=entity_texts,
)
save_results without entity_texts on a table raises. It does not write a cleartext copy.
anonymize_docx_file¶
Use this when you need to write a .docx via save_results. It returns a third value, entity_texts, that save_results requires on the Word path.
Import Signature¶
from pdf_anonymizer_core.core import anonymize_docx_file
from pdf_anonymizer_core.utils import save_results
Returns¶
review(str): Part-wise flatten of the masked document.mapping(dict[str, str]): Original → written, same asanonymize_file.entity_texts(tuple[str, ...]): The sameentity["text"]list the text engine passes toreplace_entities.
review, mapping, entity_texts = anonymize_docx_file(
"letter.docx",
characters_to_anonymize=100000,
prompt_template="",
model_name="",
use_llm=False,
)
save_results(
review,
{v: k for k, v in mapping.items()},
"letter.docx",
entity_texts=entity_texts,
)
save_results without entity_texts on a Word file raises. It does not write a cleartext copy.
deanonymize_file¶
The deanonymize_file function reads an anonymized file, loads the mapping (auto-detecting placeholder→original or legacy direction), replaces placeholders (including .v_N variants), writes the restored document to the conventional output directory (data/deanonymized/), writes a statistics JSON file (data/stats/), and returns the two output file paths.
Import Signature¶
Parameters¶
anonymized_file_path(str): Path to the markdown, text, CSV, Excel, or Word file that has placeholders.mapping_file_path(str): Path to the JSON mapping file (plaintext or*.mapping.json.enc).mapping_passphrase(str, optional): Required when the mapping file is encrypted. Also used by the CLI via--mapping-passphrase/ANONYMIZER_MAPPING_KEY.expected_source_sha256(str, optional, keyword-only): When set, an encrypted mapping locked to a different source file is rejected.
Returns¶
deanonymized_file_path(str): Path to the written restored document.stats_file_path(str): Path to the written deanonymization statistics JSON file.
Configuration & Prompts¶
The core library exposes configuration constants, model structures, and prompts in conf and prompts modules.
Loading Models & Configuration¶
from pdf_anonymizer_core.conf import (
DEFAULT_MODEL_NAME,
ModelName,
PromptEnum,
)
# Print default model
print(f"Default: {DEFAULT_MODEL_NAME}")
# List preconfigured Google models
google_models = [m.value for m in ModelName if m.provider == 'google']
print("Google models:", google_models)
Selecting a Prompt Template¶
The package provides three pre-configured prompt styles: simple, detailed, and hipaa.
detailed is the careful one. Besides names, emails, and similar labels, it asks the model to hide identity clues: phrases that point to one person without writing their name (for example "the CEO of Tesla", or "Acme Inc.'s only in-house patent counsel"). Those phrases come back as type PERSON (when the model knows the name) or type INDIRECT (when it does not). simple does not ask for this, so it stays cheaper.
hipaa is the coverage aid used by --entity-profile hipaa-safe-harbor. It is not a compliance certificate.
from pdf_anonymizer_core.prompts import simple, detailed, hipaa
# Use the detailed prompt template (recommended when identity clues matter)
prompt_text = detailed.prompt_template
A slower, classroom-style explanation is in How PDF Anonymizer is Different.
End-to-End Code Example¶
Here is a complete script demonstrating how to programmatically anonymize a document, print the details, and then programmatically restore the text.
import os
import json
from pdf_anonymizer_core.core import anonymize_file
from pdf_anonymizer_core.utils import deanonymize_file, save_results
from pdf_anonymizer_core.prompts import detailed
# 1. Anonymize the input file
input_document = "data/contract.pdf"
model = "gemini-2.5-flash"
print(f"Anonymizing {input_document} using {model}...")
anonymized_text, mapping = anonymize_file(
file_path=input_document,
characters_to_anonymize=30000,
prompt_template=detailed.prompt_template,
model_name=model,
)
# 2. Inspect the outputs
print("\n--- Masked Text Output ---")
print(anonymized_text[:500] + "\n...")
print("\n--- Extracted Mappings ---")
print(json.dumps(mapping, indent=2))
# Persist via save_results so the mapping is mode 0600 (not umask 0644).
anonymized_path, mapping_path = save_results(
anonymized_text,
{v: k for k, v in mapping.items()},
input_document,
# mapping_passphrase="secret", # optional lock
# ephemeral_mapping=True, # never write data/mappings/
)
# 3. Deanonymize programmatically
print(f"\nRestoring file from {anonymized_path} using {mapping_path}...")
deanonymized_file_path, stats_file_path = deanonymize_file(
anonymized_path,
mapping_path,
)
print("Deanonymized file saved to:", deanonymized_file_path)
print("Stats file saved to:", stats_file_path)
# If you need the text content in memory:
with open(deanonymized_file_path, "r", encoding="utf-8") as f:
restored_text = f.read()
print("\n--- Restored Text Output (first 500 chars) ---")
print(restored_text[:500] + "\n...")
You can also pass a custom list for anonymized_entities or supply your own regex_patterns dict for the first-stage NER (now RE2-powered with 70+ patterns for 30+ countries; see Recipes for examples and conf.DEFAULT_REGEX_PATTERNS).
Advanced: Caching and Full Control¶
The library caches LLM responses by default (in data/cache/llm_responses.json). You can control it directly:
from pdf_anonymizer_core.llm_provider import configure_cache
configure_cache(enabled=True, cache_dir="my-cache", cache_file="responses.json")
Related helpers (report only, they do not rewrite text):
from pdf_anonymizer_core.verify import verify_anonymized_text, write_residual_report
from pdf_anonymizer_core.risk import assess_linkage_risk, write_risk_report
write_residual_report(verify_anonymized_text(anonymized_text), anonymized_path)
write_risk_report(assess_linkage_risk(anonymized_text), anonymized_path)
For the complete anonymize_file signature (including chunk_overlap, regex_patterns, max_retries, operators, seed_mapping, gazetteers, use_llm, etc.) see the auto-generated API Reference or the Recipes page. Pass use_llm=False (or -p regex-only / --no-llm on the CLI) to skip the language model.
See Also¶
- HTTP service and Docker —
POST /anonymizeand the official image. - Recipes & Common Workflows — practical SDK examples (local Ollama, external LLM round-trips, profiles, custom regex, cache control, large files).
- CLI Reference — the command-line surface that wraps the same core functions.
- API Reference (auto) — auto-generated detailed signatures.
- Architecture Design — internals behind the functions documented here.
- Installation & Setup — how to set up the environment for the SDK.
- Troubleshooting — help with common SDK and CLI issues.