aiuti-lab
Applicazione modulare per l'analisi degli aiuti di stato italiani (OpenData 2014–2025).
Consolida in una libreria testata il know-how disperso nei notebook/script del repo
open-data-analytics: data-access, classificatori pluggable, pipeline, export.
Esterna al repo originale: legge i dati esistenti in sola lettura (data_root in
aiuti.yml punta a ../open-data-analytics/data); non modifica né duplica il corpus.
Setup
cd aiuti-lab
python -m venv .venv --system-site-packages # riusa i pacchetti base gia' presenti (pandas, pyarrow)
source .venv/bin/activate
pip install -e ".[dev]" # core + duckdb + pytest
pytest
# Metodi opzionali (solo se servono spacy/transformer/LLM):
pip install -e ".[nlp,llm]" # spacy + transformers + openai
python -m spacy download it_core_news_lg # modello per il metodo 'spacy'
Senza gli extra, il metodo regex (gazetteer, P≈0.97) e' pienamente funzionante; gli altri
metodi risultano non disponibili (aiuti methods li marca con ·) finche' non installi l'extra.
CLI
aiuti info # config risolta + file annuali trovati
aiuti count # record totali e per anno (DuckDB)
aiuti methods # metodi registrati e disponibilità
aiuti evaluate --methods regex # confronto metodi sul goldset (regex: micro_P≈0.97)
aiuti pipelines # pipeline predefinite e loro stage
aiuti run ai_tech --years 2016 --formats parquet,csv # produce out/ai_tech/2016.{parquet,csv}
aiuti run ai_gate # gate AI sottrattivo sull'intero corpus
aiuti run traceability # record di tracciabilità + profilazione
aiuti report year_share # trend AI per anno (via DuckDB) -> out/report/
aiuti report multiclass # distribuzione ambiti applicativi
aiuti report regions # importi AI per regione
aiuti endpoints # endpoint di inferenza configurati
aiuti ping bert_binary # health check di un endpoint
aiuti classify --endpoint bert_binary --out-col CLASSIF_NEW --years 2016
Inferenza su endpoint BERT (host:porta)
Per lanciare classificazioni nuove — non previste dalla pipeline legacy — punta l'app a un
modello BERT servito in un container su host:porta (localhost o rete locale del dipartimento).
Due protocolli, scelti con protocol:.
NVIDIA Triton (protocollo KServe v2):
endpoints:
bert_binary:
host: 192.168.1.50 # container Triton su LAN
port: 8000 # porta HTTP di Triton
protocol: triton
model_name: bert_binary # nome nel model repository
input_name: INPUT # tensore di input (da config.pbtxt)
batch_size: 512 # l'endpoint accetta batch di 512 testi
labels: [NON_AI, AI] # argmax dei logit -> nome classe
Costruisce POST /v2/models/{model_name}/infer con inputs BYTES, health su
/v2/health/ready. Parsing: output numerici (logit/probabilità) → argmax per riga mappato via
labels; output BYTES → etichette dirette o formato classificazione score:index:label.
simple (FastAPI/TorchServe custom): POST {texts:[...]} → {predictions:[{label,score}]},
con chiavi input_key/output_key/label_key/score_key configurabili; gestisce anche il
formato HF all-scores.
Nessuna dipendenza esterna (urllib stdlib). Usalo da CLI (aiuti ping, aiuti classify --endpoint …)
o dalla scheda 🔌 Inferenza BERT della web UI (test connessione, prova su testo singolo,
classificazione dell'intero corpus con download).
Dati in altri formati (Excel, JSON, Parquet) e altri schemi
L'app non è legata al CSV. Il formato e i nomi delle colonne si impostano in aiuti.yml
(o dalla scheda Configurazione della web UI — vedi sotto), senza toccare il codice.
annual_glob: "dati_*.xlsx" # il pattern determina i file; l'estensione dà il formato
source_format: auto # auto | csv | json | parquet | xlsx (auto = da estensione)
# Se il tuo dataset usa nomi di colonna diversi, mappali sui nomi canonici dell'app.
# Sinistra = nome usato internamente; destra = nome nel TUO file.
column_map:
DESCRIZIONE_PROGETTO: descrizione
CLASSIFICAZIONE: esito
IMPORTO_NOMINALE_TOTALE: importo
La traduzione avviene in lettura (un solo punto, aiuti_lab.sources): oracoli, pipeline e report
continuano a vedere i nomi canonici. Excel funziona out-of-the-box (openpyxl è incluso).
Web UI (Streamlit)
pip install -e ".[ui]"
streamlit run webapp/app.py
Cinque schede — Configurazione (imposta cartella dati, formato, mappatura colonne ed
endpoint e salva su aiuti.yml, tutto dai menu, senza editare file a mano; solo admin),
Corpus (conteggi + report con grafici), Pipeline (produzione dataset con download
parquet/CSV/dta), Inferenza BERT (classificazione via endpoint), Evaluate (confronto
metodi sul goldset). È un layer sottile: chiama solo aiuti_lab.*, hostabile in dipartimento.
Per lo sviluppo locale senza lo stack di autenticazione: AIUTI_AUTH_MODE=dev streamlit run webapp/app.py.
Deploy sicuro sul server (Docker) — multi-utente con login + 2FA
Chi fa questi passi. L'installazione e la configurazione (segreti, DNS, CA, utenti LDAP, 2FA) sono compiti dell'amministratore tecnico del dipartimento, una volta sola. Gli utenti finali (professori) non toccano nulla di tutto ciò: accedono via browser al portale sicuro e usano la web UI già pronta.
Un solo comando avvia app + autenticazione. Architettura Gatekeeper: è pubblicato solo il reverse proxy (Caddy), che verifica login e secondo fattore con Authelia prima di far passare qualunque richiesta a Streamlit. Identità/ruoli stanno in LLDAP (con UI web di amministrazione) e PostgreSQL; le sessioni in Redis. L'app non è mai esposta senza login.
cp .env.example .env
# genera i segreti (una volta) e incollali in .env:
openssl rand -hex 32 # per AUTHELIA_SESSION_SECRET, AUTHELIA_STORAGE_ENCRYPTION_KEY,
# AUTHELIA_JWT_SECRET, LLDAP_JWT_SECRET
openssl rand -base64 24 # per le password: POSTGRES/AUTHELIA_DB/LLDAP_DB/REDIS/LLDAP_ADMIN
# imposta anche DATA_DIR (cartella dati) e DOMAIN (default aiuti.local)
docker compose up -d
Sui client aggiungi al DNS interno (o a /etc/hosts): aiuti.local auth.aiuti.local users.aiuti.local → IP del server. WebAuthn richiede HTTPS: Caddy usa una CA interna
(importa la sua root CA nei browser per togliere l'avviso, oppure accetta il certificato).
Primo avvio (admin):
https://users.aiuti.local→ login LLDAP comeadmin(passwordLLDAP_ADMIN_PASSWORD). Crea i gruppiaiuti-userseaiuti-admins, metti te stesso inaiuti-admins.- Crea gli account degli altri (username, email, password) e assegnali a
aiuti-users. - Ogni utente, al primo accesso su
https://aiuti.local, fa login e registra il 2FA (passkey/WebAuthn o app TOTP). Il link di registrazione (notifier su file) si legge con:docker compose exec authelia cat /config/notification.txt(in produzione: configurare SMTP).
Ruoli (RBAC): chi è in aiuti-admins vede la scheda Configurazione (scrittura globale);
gli altri usano analisi, pipeline, inferenza. Più utenti lavorano in contemporanea con sessioni
isolate. La cartella dati resta in sola lettura; gli output persistono in ./out.
I certificati della CA interna sono persistiti (
caddy_data); i segreti stanno solo in.env(git-ignored). Per la massima sicurezza si possono usare i Docker secrets al posto di.env.
Architettura
aiuti_lab.config— Settings (Pydantic): unica sorgente di path/worker/chunk.aiuti_lab.corpus— Data Access Layer (Repository): DuckDB per gli scan, pandas a chunk per il lavoro riga-per-riga,map_parallelcome UNICO punto conPool/fork.aiuti_lab.text/aiuti_lab.schema— fix pandas 3.0 Arrow/RE2 e nomi colonna centralizzati.aiuti_lab.taxonomies— oracoli unici di label (ai_tech, traceability v2, ai_gate, tipo_ai, profiling); gli invarianti di correttezza sono coperti da test.aiuti_lab.methods— classificatori pluggable (Strategy + Registry + Factory): regex, spacy, transformer, llm, ensemble (primario + fallback).aiuti_lab.pipeline— stage componibili (Chain) + runner cache-first + export parquet/CSV/STATA.aiuti_lab.evaluate/aiuti_lab.report— metriche sul goldset e analisi/figure parametriche.webapp/auth.py— adapter d'identità (Gatekeeper): legge l'identità già verificata dal reverse proxy (Authelia) e fa da unico punto percurrent_user()/is_admin(). L'app dipende da queste funzioni, non dagli header (Dependency Inversion): passare a OIDC cambierebbe solo qui.
Test
pytest # 74 test: oracoli, DAL, formati (csv/json/parquet/xlsx) + mappatura colonne,
# metodi, pipeline end-to-end, export .dta, inferenza (simple/Triton),
# autenticazione (RBAC/dev-fallback/deny) + UI smoke (admin-gating)
Metadata
Release files for aiuti-analytics 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| aiuti_analytics-0.1.0.tar.gz | 43.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| aiuti_analytics-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 100.0 kB
Release files / aiuti_analytics-0.1.0.tar.gz
| Download URL | aiuti_analytics-0.1.0.tar.gz |
|---|---|
| Size | 43.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1eee2731e00d3d1575899a0fedefa215b40a936f7f9e34c2661c230efbeacd01
|
|
BLAKE2b-256 checksum How to use checksums |
8efce91651020ccdc1a2e157a5f06c0904cb81354ceef7432d10b4153ac52629
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 25, 2026.
Transparency logRelease files / aiuti_analytics-0.1.0-py3-none-any.whl
| Download URL | aiuti_analytics-0.1.0-py3-none-any.whl |
|---|---|
| Size | 56.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
cefbe055aed305e3facd6325f3bf1bad7adc757eccc6e85b3eb10f7d1e4cbdcb
|
|
BLAKE2b-256 checksum How to use checksums |
4f1b7a75f0dcda7cec668df6af918b1d5be883eaeb3a197f326fac0e3c9138a0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 25, 2026.
Transparency log