Skip to main content

API Reference

Constructor

WhosePIIGuardian(
api_key: Optional[str] = None, # AnotiAI API key (required for cloud mode)
local_mode: bool = False, # Force local mode
local_fallback: bool = True, # Fallback to local if cloud fails
base_url: Optional[str] = None # Override API base URL (advanced: for testing/custom deployments)
)

Note: base_url is optional and only needed for testing or custom deployments. Most users should omit it to use the default production backend.

Methods

mask_text(text: str, confidence_threshold: float = 0.5) -> Dict

Mask PII in text.

Parameters:

  • text (str): Text to mask
  • confidence_threshold (float): 0.0-1.0, higher = more strict (default: 0.5)

Returns:

{
"masked_text": str, # Text with PII replaced
"pii_map": Dict, # Mapping of placeholders to original PII
"entities_found": int, # Number of entities detected
"confidence_threshold": float,
"usage": {
"input_tokens": int,
"output_tokens": int,
"total_tokens": int
}
}

Example:

result = guardian.mask_text("Hi, I'm John Doe and my email is john@example.com")
print(result["masked_text"])
# "Hi, I'm [REDACTED_NAME_1] and my email is [REDACTED_EMAIL_1]"

detect_pii(text: str, confidence_threshold: float = 0.5) -> Dict

Detect PII without masking.

Returns:

{
"entities_found": int,
"pii_results": [
{
"value": str, # Original PII value
"type": str, # PII type (email, phone, person, etc.)
"start": int, # Start position
"end": int, # End position
"confidence": float # Detection confidence
},
...
],
"classification": str, # "pii_disclosure", "no_pii", etc.
"confidence": float,
"usage": {...}
}

Example:

result = guardian.detect_pii("Contact me at john@example.com")
for entity in result["pii_results"]:
print(f"{entity['type']}: {entity['value']} (confidence: {entity['confidence']})")

unmask_text(masked_text: str, pii_map: Dict) -> Dict

Restore original text from masked version.

Returns:

{
"unmasked_text": str,
"entities_restored": int,
"usage": {...}
}

Example:

mask_result = guardian.mask_text("My email is john@example.com")
unmask_result = guardian.unmask_text(
mask_result["masked_text"],
mask_result["pii_map"]
)

safe_chat(prompt: str, model_id: str, *, masking: bool = True, stream: bool = False, chat_history: Optional[List[Dict]] = None, allow_unmasked_fallback: bool = False) -> Dict | Response

Chat with LLM while automatically masking PII.

Parameters:

  • prompt (str): User prompt
  • model_id (str): Model ID (e.g., "openai:gpt-4o", "openai:gpt-4-turbo")
  • masking (bool): Enable server-side masking (default: True)
  • stream (bool): Enable streaming (default: False)
  • chat_history (List[Dict]): Chat history, format: [{"role": "user", "content": "..."}]
  • allow_unmasked_fallback (bool): Allow unmasked if masking unavailable (default: False)

Returns (non-streaming):

{
"id": str,
"choices": [{
"message": {
"role": "assistant",
"content": str
}
}],
"usage": {
"prompt_tokens": int,
"completion_tokens": int,
"total_tokens": int
}
}

Example (non-streaming):

response = guardian.safe_chat(
prompt="My email is john@example.com. Can you help?",
model_id="openai:gpt-4o",
masking=True
)
print(response["choices"][0]["message"]["content"])

Example (streaming):

import json

stream = guardian.safe_chat(
prompt="Tell me a story",
model_id="openai:gpt-4o",
stream=True,
masking=False
)

for line in stream.iter_lines(decode_unicode=True):
if line.startswith("data: "):
data = json.loads(line[6:])
if "choices" in data and data["choices"]:
content = data["choices"][0].get("delta", {}).get("content", "")
if content:
print(content, end="", flush=True)

Error Handling

from anotiai_pii_masker import (
APIError,
AuthenticationError,
RateLimitError,
ValidationError,
NetworkError
)

try:
result = guardian.mask_text(text)
except AuthenticationError:
print("Invalid API key")
except RateLimitError as e:
print(f"Rate limited. Retry after: {e.retry_after}")
except APIError as e:
print(f"API error: {e}")

Configuration

Environment Variables

export ANOTIAI_API_KEY=your_api_key
export ANOTIAI_BASE_URL=https://custom-api.example.com/anotiai

Programmatic

# Standard usage - just provide API key
guardian = WhosePIIGuardian(api_key="your_key")

# Advanced: Override base URL (only for testing/custom deployments)
guardian = WhosePIIGuardian(
api_key="your_key",
base_url="https://custom-backend.example.com/anotiai"
)

Support