Skip to main content

Python SDK for the Ciphyrs PII Shield API

Project description

Ciphyrs — PII Shield for AI Workflows

PyPI Python License: MIT

Intercept, mask, and restore PII before it reaches any LLM. Works with LangChain, CrewAI, or any Python application.

Install

pip install ciphyrs                  # core SDK
pip install 'ciphyrs[langchain]'     # + LangChain integration
pip install 'ciphyrs[crewai]'        # + CrewAI integration
pip install 'ciphyrs[all]'           # everything

Quick Start

from ciphyrs import CiphyrsClient

client = CiphyrsClient(
    api_key="cyp_live_...",
    base_url="https://www.ciphyrs.com"
)

# Mask PII
result = client.mask("Contact Praveen at 9876125640 and praveen@acme.com")
print(result.masked_text)
# "Contact XXXX_a1b2c3 at XXXX_d4e5f6 and XXXX_g7h8i9"

# Restore PII
restored = client.restore(result.masked_text, result.session_id)
print(restored.restored_text)
# "Contact Praveen at 9876125640 and praveen@acme.com"

One-Shot Protect (recommended)

protect() wraps mask → LLM call → restore so you can't accidentally ship [PERSON_1] to end users:

from openai import OpenAI
oai = OpenAI()

result = client.protect(
    user_message,
    lambda masked, ctx: oai.chat.completions.create(
        model="gpt-4o",
        messages=[{"role": "user", "content": masked}],
    ).choices[0].message.content,
)
return result["output"]    # "Hello John, ..." — never "[PERSON_1]"

Active Blocking — Guard (V58)

Inline <50ms allow/block decision, 5 detection layers:

# Option 1 — manual check
guard = client.guard_check(input=user_msg, agent_name="support-bot")
if guard["decision"] == "block":
    return {"error": guard["reason"]}, 400

# Option 2 — full wrap
result = client.guard_wrap(user_msg, lambda inp:
    oai.chat.completions.create(
        model="gpt-4o",
        messages=[{"role": "user", "content": inp}],
    ).choices[0].message.content
)
if result["blocked"]:
    return {"error": result["reason"]}, 400
return {"reply": result["output"]}

Security Operations (V55-V59)

# List recent attacks
detections = client.list_detections(days=7, severity="high")

# Plant a honeypot canary
created = client.create_canary(name="fake-admin-secret", scope="output")
print(created["token"])   # save this; plant it where it shouldn't appear

# Generate compliance evidence PDF
report = client.generate_prod_report(
    title="Q4 SOC 2 Evidence",
    range_start="2026-10-01",
    range_end="2026-12-31",
    sections=["security_incidents", "pii_detections", "performance", "cost"],
)
pdf_bytes = client.download_prod_report_pdf(report["report"]["id"])
open("soc2-evidence.pdf", "wb").write(pdf_bytes)

# Share with auditors (no login required)
share = client.share_prod_report(report["report"]["id"], ttl_days=30)
print(share["share_url_path"])

Authentication

All API calls require an x-api-key header. Get your API key from the Ciphyrs Dashboard.

  1. Register at ciphyrs.com/register
  2. Go to Settings > API Keys
  3. Click Generate API Key
  4. Copy the key (starts with cyp_live_)

LangChain Integration

Option 1: Callback Handler (auto-masks all LLM calls)

from langchain_openai import ChatOpenAI
from ciphyrs.integrations.langchain import CiphyrsPIICallback

callback = CiphyrsPIICallback(api_key="cyp_live_...")
llm = ChatOpenAI(model="gpt-4o", callbacks=[callback])

# PII is automatically masked before reaching OpenAI
# and restored in the response
result = llm.invoke("Hi, I'm Praveen Kumar, my phone is 9876125640")

Option 2: LCEL Runnables (pipe operator)

from ciphyrs.integrations.langchain import CiphyrsMaskRunnable, CiphyrsRestoreRunnable

session = {}
mask = CiphyrsMaskRunnable(api_key="cyp_live_...", session_store=session)
restore = CiphyrsRestoreRunnable(api_key="cyp_live_...", session_store=session)

# Build pipeline: mask -> prompt -> llm -> restore
chain = mask | prompt_template | llm | restore
result = chain.invoke({"input": "Call Praveen at 9876125640"})

Option 3: Shield Wrapper (wrap any chain)

from ciphyrs.integrations.langchain import CiphyrsShield

shield = CiphyrsShield(api_key="cyp_live_...")
safe_chain = shield.wrap(my_existing_chain)
result = safe_chain.invoke({"input": "Praveen's email is praveen@acme.com"})

Async Support

from ciphyrs import AsyncCiphyrsClient

async with AsyncCiphyrsClient(api_key="cyp_live_...") as client:
    result = await client.mask("Contact Praveen at praveen@acme.com")
    restored = await client.restore(result.masked_text, result.session_id)

Detected Entity Types

Entity Example
PERSON Praveen Kumar
EMAIL praveen@acme.com
PHONE 9876125640
IN_AADHAAR 2345 6789 0123
IN_PAN ABCDE1234F
CREDIT_CARD 4111-1111-1111-1111
IP_ADDRESS 192.168.1.1
DATE_OF_BIRTH 15/03/1990
LOCATION Mumbai
ORGANIZATION Acme Corp
API_KEY sk-abc123...

Links

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ciphyrs-2.5.0.tar.gz (56.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ciphyrs-2.5.0-py3-none-any.whl (84.7 kB view details)

Uploaded Python 3

File details

Details for the file ciphyrs-2.5.0.tar.gz.

File metadata

  • Download URL: ciphyrs-2.5.0.tar.gz
  • Upload date:
  • Size: 56.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for ciphyrs-2.5.0.tar.gz
Algorithm Hash digest
SHA256 2001a1f4090fdac80a6e7f4ffc2a7b77332ac88ddd55838845df9d1bcf31c4d6
MD5 3e4280215ed12ed6a1787248096a6968
BLAKE2b-256 5677accbc7cf3b4e50fd67f96bceaea0c95232fc07446c815a40d4fb0b0d43f2

See more details on using hashes here.

File details

Details for the file ciphyrs-2.5.0-py3-none-any.whl.

File metadata

  • Download URL: ciphyrs-2.5.0-py3-none-any.whl
  • Upload date:
  • Size: 84.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.7

File hashes

Hashes for ciphyrs-2.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8c37b0f63bb713149734b6bd9e35ef8c1e66766822681f9b0807b93bc5f98901
MD5 1d992fad5bcca8c5c96d5f6dd09eff55
BLAKE2b-256 51b514442d35eaf539fd3b94646cd2bf4949124eb8bc23f9e80e971c97f5ac0e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page