fix(pipeline): fallback DuckDB sniff, estrazione anni, circuit breaker condiviso - #413
Merged
Merged
Conversation
…r condiviso Tre fix della pipeline di validazione (source-observatory): 1. Fallback DuckDB nello sniff CSV: il parser standard (csv.Sniffer + DictReader) fallisce su SDMX-CSV e CSV con newline nei campi non quotati. DuckDB li gestisce: recupera 43/112 gruppi 'reachable senza schema' (INPS 37, ministero_interno 4, pagopa 1, unioncamere 1). 2. Estrazione range anni: popola dataset_group_year_min/max da tre strategie (nomi colonna -> valori via DuckDB -> filename). Nel run completo: gruppi con anni 101 -> 2751 (INPS 0 -> 1764). Include il fix del NaN: il merge pandas produce NaN non None, il check 'is None' non scattava e gli anni non venivano propagati. 3. Circuit breaker condiviso nella pipeline: un solo HttpClient con circuit_threshold=3 per tutta la run, passato a probe/sniff. Host giu' (es. lavoro_opendata) bloccati dopo 3 errori invece di ~11s per gruppo: run completo da ~15min+ a ~8min. Fix timeout da 60s a 5s (il default del client faceva bruciare ~114s per fallimento). Dipende dalla PR #73 in lab-connectors (fix verify duplicato nel fallback SSL HEAD): senza, ministero_salute torna a perdere 38 CSV. lab-connectors installato in editable locale per test.
Stabilizzazione CI: - test di rete (MEF/httpstat.us) marcati smoke: la CI non deve dipendere da fonti esterne. I rami prima coperti solo dalla rete ora hanno test deterministici con fake_http (lab_connectors.testing). - coverage repo 58% -> 64% (sopra la soglia 60%), coprendo codice di produzione che gira in CI senza test: * sparql.py (collector 5 fonti radar): 15% -> 84% * gha/gcs_upload.py (in CI): 0% -> 100% * gha/publish_radar_summary.py (in CI): 0% -> 100% * sync_datasets_in_use.py (in CI): 0% -> 75% * _validate_base.py: 81% -> 89% (rami di errore/NaN/anni) Tutti i test usano mock (fake_http, monkeypatch) — nessuna rete. 298 test non-smoke + 23 smoke, tutti verdi.
- test_validate_one_without_client_creates_own: patch su scripts.collectors._validate_base.HttpClient (nome bindato nel modulo) invece di lab_connectors.http.HttpClient — con lab-connectors installato come pacchetto (CI) il path sul modulo sorgente non intercetta il nome gia' importato; in locale (editable) passava comunque. - TestSmokeNetwork: skip (non fail) quando la fonte esterna non risponde (timeout/connection) — la CI non deve dipendere da MEF/ACI vivi. Il fallimento reale del codice resta coperto dai test deterministici. 321 test passati, coverage 68% (>60).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Sintesi
Tre fix della pipeline di validazione SO (
scripts/pipeline/run_pipeline.py+scripts/collectors/), che migliorano copertura, dati e velocità delvalidated.parquet.Contesto collegato
Nessuna issue dedicata — emersi da diagnosi pipeline (attrito SO→DI): 268 CSV "reachable senza schema", 0 gruppi con anni su fonti grosse (INPS), run completo lento su host giù.
Dipendenza: PR lab-connectors#73 (fix verify duplicato nel fallback SSL HEAD). Senza di essa, ministero_salute torna a perdere 38 CSV. Da mergiare prima o insieme.
Cosa cambia
Dettaglio fix
1. Fallback DuckDB nello sniff CSV (
_validate_base.py)Il parser standard (
csv.Sniffer+DictReader) fallisce su SDMX-CSV e CSV con newline nei campi non quotati → gruppi "reachable ma senza schema". DuckDB li gestisce. Risultato reale (run completo): +43 gruppi profilati (INPS 37, ministero_interno 4, pagopa 1, unioncamere 1).2. Estrazione range anni (
_extract_year_range+ propagazione)Popola
dataset_group_year_min/maxcon 3 strategie: anni da nomi colonna → valori via DuckDB tipizzato → filename. Include fix del NaN (il merge pandas produceNaN, nonNone: il checkis Nonenon scattava e gli anni restavano vuoti). Risultato reale (run completo): gruppi con anni 101 → 2.751 (INPS 0 → 1.764, openga 401, unioncamere 142).3. Circuit breaker condiviso (
run_pipeline.py+ firme validate)Un solo
HttpClient(circuit_threshold=3, timeout=5)per tutta la run, passato aprobe_reachability/sniff_csv_schema/validate_tabular_group(e ai validatori ckan/sdmx/sparql, che accettanoclient— sdmx/sparql lo ignorano). Host giù (lavoro_opendata, dati.anticorruzione.it, bdap-opendata) bloccati dopo 3 errori invece di ~11s per gruppo. Run completo: ~15min+ → 8min. Nota:timeout=5corretto — il default 60s del client faceva bruciare ~114s per fallimento prima dell'apertura del circuito.Verifica
pytest tests/ ruff check . mypy scripts/ so_mcp/pytest tests/pipeline/test_validate_utils.pypassa (25 test, 5 nuovi:TestExtractYearRange+ fallback DuckDB)ruff check scripts/passamypy scripts/collectors/_validate_base.py scripts/pipeline/run_pipeline.pypassarun_pipeline --workers 8→ 11.129 gruppi in 484,8s. BEFORE vs AFTER: csv profilati 2.914→2.957, con_anni 101→2.751, ministero_salute 2→40 profilatiCircuit open for host), centinaia di gruppi skippati in msNote per chi revisiona
dati.anticorruzione.itoggi rispondeInvalidBodyLengthError(probe diretto confermato). Era vivo al 27/07. Drift di fonte, non dei fix.dfb_st_*a riga unica (reshape non banale, dati fermi 2015-2022 → condizionato ad aggiornamento fonte).validated.parquetrigenerato vive in/tmp/opencode/validated_full.parquet(non versionato nel repo) — la CI lo rigenererà al merge.