Document anonymization API on GPU: anonymize DOCX, XLSX, PDF, text, use any AI, restore.
298
Servizio di anonimizzazione documenti in un container Docker con API HTTP. Riceve TXT, MD, CSV,
PDF (digitali e scansionati), DOCX/DOCM e XLSX/XLSM e restituisce lo stesso file, nello stesso
formato, con i dati personali sostituiti da segnaposto ([FULLNAME_1], [CF_1], …), più un report
JSON senza dati personali. Rilevamento: modello GLiNER2-PII (fastino, Apache-2.0) su GPU in fp16,
con schema di etichette configurabile, regole deterministiche e una rete regex con checksum. Specifica completa dentro l'immagine: /app/docs/SPEC_anonimizzatore.md.
sm_120); l'immagine contiene i kernel
sm_120 e anche quelli per le architetture precedenti.-e DEVICE=cpu (più lento).docker pull aivanovitch/omissis:1.2
docker run -d --name omissis --gpus all --cpus 1 --memory 3g \
--read-only --tmpfs /tmp -p 127.0.0.1:8080:8080 aivanovitch/omissis:1.2
curl -s localhost:8080/ready # 200 quando il modello è caricato
Il modello viene scaricato da Hugging Face durante la build e verificato con model.sha256; a
runtime il container non esce mai in rete. Avviare Omissis prima dell'LLM che condivide la GPU.
Per integrarlo in un'altra piattaforma, anche come filtro davanti a un LLM esterno (anonimizza il prompt, ricostruisce la risposta): INTEGRATION.md (anche nell'immagine, in /app/docs/INTEGRATION.md).
| Da dove | Indirizzo |
|---|---|
| Stessa macchina (browser, curl, app sull'host) | http://127.0.0.1:8080 |
| Un altro container sulla stessa macchina | http://172.17.0.1:8080, oppure http://host.docker.internal:8080 se quel container ha --add-host host.docker.internal:host-gateway |
| Documentazione interattiva (Swagger) | http://127.0.0.1:8080/docs |
| Schema OpenAPI, per configurare client e agent | http://127.0.0.1:8080/openapi.json |
Il servizio non è esposto sulla rete locale: le porte sono pubblicate solo su 127.0.0.1 e
sull'interfaccia docker0 (vedi il comando di avvio qui sotto).
docker run -d --name omissis --restart unless-stopped \
--gpus all --cpus 1 --memory 3g --read-only --tmpfs /tmp \
--env-file .env.local \
-p 127.0.0.1:8080:8080 -p 172.17.0.1:8080:8080 \
aivanovitch/omissis:1.0
.env.local (fuori da git) contiene API_KEY=...: la stessa configurazione della produzione.
Variabili d'ambiente principali (tutte in SPEC 9):
| Variabile | Default | Significato |
|---|---|---|
DEVICE | cuda | cuda o cpu |
VRAM_LIMIT_GB | 2 | Tetto di VRAM del processo |
BATCH_SIZE | 16 | Chunk per chiamata al modello (dimezzato in automatico se la VRAM non basta) |
INFERENCE_WORKERS | 1 | Processi worker (sempre 1 con cuda) |
API_KEY | vuoto | Se impostata, Authorization: Bearer <API_KEY> obbligatorio |
MAX_UPLOAD_MB / MAX_PAGES / MAX_QUEUE | 50 / 500 / 50 | Limiti di upload e coda |
SYNC_TIMEOUT_S / JOB_TIMEOUT_S / RESULT_TTL_S | 60 / 900 / 600 | Tempi |
DELETE_ON_DOWNLOAD | true | Cancella il risultato dopo il download |
ALLOW_REVERSIBLE | true | Modalità reversibile (default): restituisce il dizionario per ricostruire. false = tutto definitivo |
OCR_ENABLED / OCR_JOBS | true / 1 | OCR dei PDF scansionati |
DEFAULT_EXCLUDE_TAGS | vuoto | Tag lasciati in chiaro, separati da virgola |
TMP_BUDGET_MB | 400 | /tmp è in RAM: oltre questo spazio tra file in coda e risultati non scaricati, 429 |
LABELS_FILE | vuoto | Schema di etichette alternativo: etichetta del modello → tag, descrizione, soglia (formato di omissis/engine/labels.json) |
LOG_LEVEL | INFO | I log non contengono mai dati personali |
# Sincrono: restituisce direttamente il file (header X-Job-Id, X-Anon-Status)
curl -s -F [email protected] localhost:8080/v1/anonymize -o contratto_anon.docx -D -
# Con opzioni
curl -s -F [email protected] \
-F 'options={"exclude_tags":["AMOUNT"],"pdf_label_style":"short","ocr":"auto"}' \
localhost:8080/v1/anonymize -o atto_anon.pdf
# Asincrono: crea il job, leggi stato e report, scarica il risultato
curl -s -F [email protected] localhost:8080/v1/jobs # {"job_id": "...", "status": "queued"}
curl -s localhost:8080/v1/jobs/<job_id> # stato + report
curl -s localhost:8080/v1/jobs/<job_id>/result -o anagrafica_anon.xlsx
curl -s localhost:8080/v1/jobs/<job_id>/mapping # solo modalità reversibile, altrimenti 404
curl -s -X DELETE localhost:8080/v1/jobs/<job_id>
# Testo: anonimizza (con il dizionario della conversazione) e ricostruisci
curl -s -H 'Content-Type: application/json' -H "Authorization: Bearer $API_KEY" \
-d '{"text":"Scrivi a Mario Rossi","mapping":{"[FULLNAME_1]":"Anna Verdi"}}' \
localhost:8080/v1/text/anonymize
curl -s -H 'Content-Type: application/json' -H "Authorization: Bearer $API_KEY" \
-d '{"text":"Caro [FULLNAME_2]","mapping":{"[FULLNAME_2]":"Mario Rossi"}}' \
localhost:8080/v1/text/restore
# Solo rilevamento su testo (entità senza valori)
curl -s -H 'Content-Type: application/json' \
-d '{"text":"Il signor Mario Rossi, CF RSSMRA85H12F205Y","exclude_tags":["DATE"]}' \
localhost:8080/v1/analyze
# Stato del servizio
curl -s localhost:8080/health
curl -s localhost:8080/ready
curl -s localhost:8080/metrics
Con API_KEY impostata aggiungere -H "Authorization: Bearer $API_KEY" alle chiamate /v1/*.
Codici di errore: 400 opzioni o file non validi, 401 autenticazione, 413 file o pagine oltre
il limite, 415 formato non supportato, 422 PDF protetto, scansione senza OCR o job blocked
(sincrono), 429 coda piena.
options del multipart, JSON){
"mode": "reversible",
"exclude_tags": ["AMOUNT"],
"pdf_label_style": "placeholder",
"ocr": "auto",
"xlsx_numeric_policy": "to_string",
"xlsx_column_policy": true,
"surname_propagation": true
}
| Campo | Valori | Default |
|---|---|---|
mode | reversible (restituisce il dizionario, /mapping) o definitive (nessun dizionario) | reversible |
exclude_tags | tag da lasciare in chiaro, tra quelli sotto | [] |
pdf_label_style | placeholder ([FULLNAME_1]), short ([N1], legenda nel report), box (riquadro pieno) | placeholder |
ocr | auto, force, off | auto |
xlsx_numeric_policy | to_string (la cella diventa testo col segnaposto) o fake_digits (cifre casuali, resta numero) | to_string |
xlsx_column_policy | maschera tutta la colonna se ≥60% delle celle (su ≥5) ha lo stesso tag; vale anche per CSV | true |
surname_propagation | il cognome di un nome completo prende lo stesso segnaposto ovunque | true |
Tag: FULLNAME AGE GENDER DATE TIME STREET BUILDINGNUM ZIPCODE CITY PROVINCE EMAIL TELEPHONENUM CF PIVA ID_DOC IBAN CREDITCARDNUMBER AMOUNT TARGA ORG DOCID CATASTO URL IPADDR.
GET /v1/jobs/{id}, mai valori personali){
"job_id": "…", "status": "done", "format": "docx",
"report": {
"status": "done", "mode": "definitive", "model": "fastino/gliner2-privacy-filter-PII-multi@36126f6",
"pages_or_parts": 5, "entities": {"FULLNAME": 14, "CF": 2}, "unique_values": 9,
"by_source": {"modello": 11, "regex": 6, "colonna": 1},
"propagated_occurrences": 23, "skipped_propagation": 0,
"residual": [], "structure_checks": {"passed": true, "details": []},
"warnings": ["…"], "timings_ms": {"extract": 12, "detect": 40, "write": 9, "verify": 3}
}
}
Stati: queued, running, done, blocked (un valore è rimasto leggibile o la struttura è
cambiata: il file non viene consegnato), failed, expired. Per integrare un'altra piattaforma la
via più semplice è POST /v1/anonymize: risponde col file (200), con 202 + job_id se supera
SYNC_TIMEOUT_S, con 422 + report se il job è blocked.
Il codice di questo servizio è rilasciato sotto PolyForm Noncommercial License 1.0.0 — testo completo anche su https://polyformproject.org/licenses/noncommercial/1.0.0.
L'uso non commerciale è consentito nei termini della licenza. Qualsiasi uso commerciale richiede una licenza separata.
Copyright © 2026 Aleksandr Ivanovitch. I diritti di proprietà intellettuale (IP) e ogni altro diritto correlato sul codice (codice sorgente, architettura, design delle API e logica di orchestrazione) appartengono ad Aleksandr Ivanovitch — vedi il file /app/NOTICE dentro l'immagine (insieme a /app/LICENSE). Per licenze commerciali e questioni di IP: @AIvanovitch su GitHub.
I pesi fastino/gliner2-privacy-filter-PII-multi (Apache-2.0), PyMuPDF e Ghostscript (AGPL-3.0) e le altre librerie elencate in /app/docs/THIRD_PARTY_NOTICES.md non sono coperti dalla licenza di questo servizio.
Content type
Image
Digest
sha256:394dbdbd0…
Size
3.7 GB
Last updated
about 9 hours ago
docker pull aivanovitch/omissis