Skip to main content

gheim

gheim (Python). PII round-trip for LLM APIs.

PyPI Python 3.11+ Apache 2.0

Detect PII in text, substitute it with stable sentinels (<PERSON_1>, <EMAIL_2>, ...), send the redacted text to any LLM, and restore the originals on the way back, including in streamed responses. The package is framework-agnostic and ships a drop-in openai client wrapper for zero-effort integration.

See the monorepo README for the cross-language overview and architecture.

Install

uv add gheim                          # core: pairs with a RemoteDetector or GHEIM_API_KEY
uv add "gheim[local]"                 # + torch and transformers for on-device detection
uv add "gheim[openai]"                # + drop-in OpenAI client
uv add "gheim[local,openai]"          # both

Model choice

LocalDetector runs a token-classification model in process. The package's default model is joelbarmettler/gheim-ch-560m — a 560M xlm-roberta-large fine-tune optimised for Swiss-market PII (test strict F1 0.910, char F1 0.946 on Swiss text, see MODEL_CARD.md). Any HuggingFace token-classification model that emits the same 33-class BIOES schema can be substituted via the model_id constructor arg.

Model Best for Parameters Notes
joelbarmettler/gheim-ch-560m (default) Production / commercial. Swiss court / parliament / web text with CH-format account numbers (IBAN, AHV, VAT-CHE) 560M Apache 2.0. Test strict F1 0.910, char F1 0.946.
joelbarmettler/gheim-ch-560m-research Research / non-commercial. Stronger cross-domain transfer on Swiss-news text (swissner PER char F1 0.90 vs 0.70 on the default) 560M CC BY-NC-SA 4.0 + Reuters research-only rider. In-distribution numbers identical to the default.
openai/privacy-filter English-first or general use, long-context (up to 128k tokens) 1.4B (50M active, MoE) Apache 2.0. Wider language coverage, larger weights.
from gheim import LocalDetector

# Default — Swiss-tuned, 560M, Apache 2.0:
det = LocalDetector()

# Stronger cross-domain transfer (research, non-commercial):
det = LocalDetector(model_id="joelbarmettler/gheim-ch-560m-research")

# Alternative for English or general use:
det = LocalDetector(model_id="openai/privacy-filter")

Drop-in OpenAI client

from gheim.openai import OpenAI

client = OpenAI()  # same constructor args as openai.OpenAI
r = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "Hi, my name is Joel"}],
)
# r.choices[0].message.content contains "Joel".
# OpenAI only ever saw "<PERSON_1>".

Custom endpoint or key (e.g. OpenRouter, local vLLM):

client = OpenAI(api_key="sk-or-...", base_url="https://openrouter.ai/api/v1")

Streaming:

stream = client.chat.completions.create(..., stream=True)
for chunk in stream:
    print(chunk.choices[0].delta.content or "", end="", flush=True)

Async:

from gheim.openai import AsyncOpenAI
client = AsyncOpenAI()
r = await client.chat.completions.create(...)

Per-call overrides:

from gheim import Session
session = Session()  # reuse across calls for multi-turn coherent sentinels
r = client.chat.completions.create(
    model="gpt-4o",
    messages=[...],
    gheim_session=session,    # or gheim_detector=...
)

Framework-agnostic

from gheim import Session, LocalDetector, anonymize_text, deanonymize_text

session = Session(detector=LocalDetector())  # gheim-ch-560m by default
clean = anonymize_text("Hi, my name is Joel", session)
# ... call any LLM with clean ...
final = deanonymize_text(response_text, session)

Streaming deanonymizer:

from gheim import deanonymize_stream
for chunk in deanonymize_stream(my_chunk_iterator, session):
    print(chunk, end="", flush=True)

Chat-message helpers:

from gheim import anonymize_messages

redacted = anonymize_messages(messages, session)  # preserves role, name, tool_call_id

Wrapped endpoints

The drop-in OpenAI / AsyncOpenAI clients automatically protect every text-carrying endpoint: chat.completions, responses, completions (legacy), embeddings, moderations, audio.speech, audio.transcriptions, audio.translations, images.generate, images.edit. Tool-call arguments and SSE delta chunks are restored on the way back. See the monorepo README for the full coverage matrix and the embeddings caveat.

Strict mode

gheim_strict=True (default) raises RuntimeError if you call an unwrapped endpoint (beta.assistants, batches, files, uploads, fine_tuning, vector_stores). The error message names client.raw.<path> as the documented escape hatch.

client = OpenAI(gheim_strict=False)  # downgrade to one-time warnings
client.raw.beta.assistants.create(...)  # always works regardless of strict mode

Detector backends

import torch
from gheim import LocalDetector, RemoteDetector, default_detector

# Local inference. Weights download to the HF cache on first use.
# `model_id` defaults to "joelbarmettler/gheim-ch-560m"; pass
# `dtype=torch.bfloat16` for half-precision GPU inference.
det = LocalDetector(device="auto", dtype=torch.bfloat16)

# Remote inference against your own gheim-server or api.gheim.ch.
det = RemoteDetector(base_url="http://your-host:8080", api_key="...")

# default_detector() picks remote if GHEIM_API_KEY is set, else local.
det = default_detector()

Composite detector (recommended for production)

For categories where structure is verifiable by checksum (CH-IBAN, AHV, VAT-CHE, credit cards, common token formats) the package ships a regex catalogue under gheim.detectors.composite that pairs with the model detector. The composite detector applies regex first, masks matched spans, then runs the model on the remainder. This pushes effective recall on account_number, private_phone, and private_url close to 1.0 with high precision; the underlying ML model handles person names, addresses, and dates.

Consulting

gheim is built and maintained by Souverana, a Swiss AI consulting business helping companies build secure, privacy-first AI systems — on-premise LLM deployments, PII/data-protection engineering, and Swiss-market NLP. If you need help integrating gheim or building compliant AI, get in touch at souverana.ch.

License

Apache 2.0. Bundled model weights are inherited from the upstream license of the model you select.

Download files

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

Source Distribution

gheim-0.1.7.tar.gz (42.1 kB view details)

Uploaded Source

Built Distribution

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

gheim-0.1.7-py3-none-any.whl (54.5 kB view details)

Uploaded Python 3

File details

Details for the file gheim-0.1.7.tar.gz.

File metadata

  • Download URL: gheim-0.1.7.tar.gz
  • Upload date:
  • Size: 42.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for gheim-0.1.7.tar.gz
Algorithm Hash digest
SHA256 38d795a32d92558888de6fb1856b249fb1237018d896333594e54f55418d0262
MD5 6253982010b507829a4c75454215c4e5
BLAKE2b-256 04b4f2e9fb38b91fbdd7e27a9e92c8412e3fa7131448ca9dce82154493a7c0af

See more details on using hashes here.

Provenance

The following attestation bundles were made for gheim-0.1.7.tar.gz:

Publisher: release.yml on joelbarmettlerUZH/gheim

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file gheim-0.1.7-py3-none-any.whl.

File metadata

  • Download URL: gheim-0.1.7-py3-none-any.whl
  • Upload date:
  • Size: 54.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for gheim-0.1.7-py3-none-any.whl
Algorithm Hash digest
SHA256 9375f6fd2f742d62faad0281f3b48ef95bdd52a0df3e92ccacb8b67dd038b241
MD5 948bf98553b778eb4a93f7f9b210049e
BLAKE2b-256 998b78c55f450d33cd69434d5fa43b0b9f05d1670c32ac02b2b3dbb1836a97d7

See more details on using hashes here.

Provenance

The following attestation bundles were made for gheim-0.1.7-py3-none-any.whl:

Publisher: release.yml on joelbarmettlerUZH/gheim

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

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