Aller au contenu

Démarrage rapide

Installation

Prérequis

  • Python 3.12+
  • uv (recommandé) ou pip

Installation basique

uv add piighost
pip install piighost

Installation pour le développement

git clone https://github.com/Athroniaeth/piighost.git
cd piighost
uv sync

Usage 1 Anonymisation standalone

L'usage le plus simple : créer un Anonymizer et l'appeler directement.

from gliner2 import GLiNER2
from piighost.anonymizer import Anonymizer, GlinerDetector

# 1. Charger le modèle NER
model = GLiNER2.from_pretrained("fastino/gliner2-multi-v1")

# 2. Créer le détecteur
detector = GlinerDetector(model=model, threshold=0.5, flat_ner=True)

# 3. Créer l'anonymiseur
anonymizer = Anonymizer(detector=detector)

# 4. Anonymiser
result = anonymizer.anonymize(
    "Patrick habite à Paris. Patrick aime Paris.",
    labels=["PERSON", "LOCATION"],
)

print(result.anonymized_text)
# <<PERSON_1>> habite à <<LOCATION_1>>. <<PERSON_1>> aime <<LOCATION_1>>.

# 5. Désanonymiser
original = anonymizer.deanonymize(result)
print(original)
# Patrick habite à Paris. Patrick aime Paris.

Labels disponibles

Les labels supportés dépendent du modèle GLiNER2 utilisé. "fastino/gliner2-multi-v1" supporte notamment "PERSON", "LOCATION", "ORGANIZATION", "EMAIL", "PHONE".


Usage 2 Pipeline avec cache de session

AnonymizationPipeline encapsule l'Anonymizer avec un cache de session pour réutiliser les placeholders entre plusieurs messages.

import asyncio
from piighost.pipeline import AnonymizationPipeline

pipeline = AnonymizationPipeline(
    anonymizer=anonymizer,
    labels=["PERSON", "LOCATION"],
)

async def main():
    # Anonymisation (async, avec cache)
    result = await pipeline.anonymize("Patrick habite à Paris.")
    print(result.anonymized_text)
    # <<PERSON_1>> habite à <<LOCATION_1>>.

    # Désanonymisation synchrone par remplacement de chaîne
    restored = pipeline.deanonymize_text("<<PERSON_1>> habite à <<LOCATION_1>>.")
    print(restored)
    # Patrick habite à Paris.

    # Reanonymisation (inverse : original → placeholder)
    reanon = pipeline.reanonymize_text("Résultat pour Patrick à Paris")
    print(reanon)
    # Résultat pour <<PERSON_1>> à <<LOCATION_1>>

asyncio.run(main())
Cache SHA-256

Le pipeline calcule un hash SHA-256 du texte source. Si le même texte est soumis plusieurs fois, le résultat mis en cache est retourné immédiatement sans appel au modèle NER.


Usage 3 Middleware LangChain

Pour intégrer l'anonymisation dans un agent LangGraph, utilisez PIIAnonymizationMiddleware :

from langchain.agents import create_agent
from langchain_core.tools import tool

from piighost.anonymizer import Anonymizer, GlinerDetector
from piighost.middleware import PIIAnonymizationMiddleware
from piighost.pipeline import AnonymizationPipeline

@tool
def send_email(to: str, subject: str, body: str) -> str:
    """Envoie un email à l'adresse donnée."""
    return f"Email envoyé à {to}."

# Construire la stack d'anonymisation
detector = GlinerDetector(model=model, threshold=0.5, flat_ner=True)
anonymizer = Anonymizer(detector=detector)
pipeline = AnonymizationPipeline(anonymizer=anonymizer, labels=["PERSON", "LOCATION"])
middleware = PIIAnonymizationMiddleware(pipeline=pipeline)

# Créer l'agent avec le middleware
agent = create_agent(
    model="openai:gpt-4o-mini",
    system_prompt="Tu es un assistant utile.",
    tools=[send_email],
    middleware=[middleware],
)

Le middleware intercepte automatiquement chaque tour de l'agent le LLM ne voit que du texte anonymisé, les outils reçoivent les vraies valeurs, et les messages affichés à l'utilisateur sont désanonymisés.


Commandes de développement

uv sync                      # Installer les dépendances
make lint                    # Format (ruff) + lint (ruff) + type-check (pyrefly)
uv run pytest                # Lancer tous les tests
uv run pytest tests/ -k "test_name"  # Lancer un test spécifique