Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
126 changes: 68 additions & 58 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,73 @@
# DataCivicLab Toolkit

Toolkit Python per pipeline dati riproducibili `RAW -> CLEAN -> MART`, con approccio SQL-first, audit degli artefatti e run tracking persistente.
Dato un `dataset.yml` e del SQL, il toolkit scarica i dati pubblici, li trasforma
e produce un mart pronto per l'analisi. Un solo comando e' sufficiente per far
girare l'intera pipeline:

```bash
toolkit run all --config dataset.yml
```

Richiede Python 3.10+. Non serve installare DuckDB separatamente.

## Installazione

```bash
git clone https://github.com/dataciviclab/toolkit.git
cd toolkit
pip install -e .[dev]
```

## Quickstart

Prova il toolkit in pochi minuti con il progetto di esempio incluso nella repo,
senza bisogno di dati reali.

Windows PowerShell:

```powershell
pip install -e ".[dev]"
toolkit run all -c project-example/dataset.yml
toolkit validate all -c project-example/dataset.yml
toolkit status --dataset project_example --year 2022 --config project-example/dataset.yml
```

Linux/macOS:

```bash
pip install -e ".[dev]"
toolkit run all -c project-example/dataset.yml
toolkit validate all -c project-example/dataset.yml
toolkit status --dataset project_example --year 2022 --config project-example/dataset.yml
```

Se il comando `toolkit` non e' nel `PATH` dopo l'installazione, puoi usare
direttamente il modulo Python:

```bash
python -m toolkit.cli.app run all --config dataset.yml
```

Il percorso canonico per i repo dataset clonati dal template e':

1. `toolkit run all --config dataset.yml`
2. `toolkit validate all --config dataset.yml`
3. `toolkit status --dataset <dataset> --year <year> --latest --config dataset.yml`
4. notebook locali che leggono gli output reali sotto `root/data/...`

Per leggere gli output dal notebook senza duplicare la path logic:

```bash
toolkit inspect paths --config dataset.yml --year 2024 --json
```

Contratto completo tra toolkit e notebook: [docs/notebook-contract.md](docs/notebook-contract.md)

Validazione rapida della config prima di eseguire la pipeline:

```bash
toolkit run all --config dataset.yml --dry-run
```

## Ruolo Nell'Ecosistema

Expand Down Expand Up @@ -48,63 +115,6 @@ Il toolkit include:
- comandi CLI `run`, `resume`, `status`, `validate`, `profile`, `inspect`
- `project-example/` offline per smoke test locale

## Installazione

```bash
git clone https://github.com/dataciviclab/toolkit.git
cd toolkit
pip install -e .[dev]
```

Richiede Python 3.10+.

## CLI Naming Note

Il comando CLI canonico del progetto e' `toolkit`.

Se nel tuo ambiente c'e' una collisione di nome o il console script non e' nel `PATH`, puoi usare direttamente il modulo Python:

```bash
python -m toolkit.cli.app run all --config dataset.yml
```

## Quickstart

Il percorso canonico per i repo dataset clonati dal template e':

1. `toolkit run all --config dataset.yml`
2. `toolkit validate all --config dataset.yml`
3. `toolkit status --dataset <dataset> --year <year> --latest --config dataset.yml`
4. notebook locali che leggono gli output reali sotto `root/data/...`

Giro offline completo con il progetto di esempio, eseguibile in pochi minuti su una macchina pulita.

Windows PowerShell:

```powershell
$env:TOOLKIT_OUTDIR = Join-Path $env:TEMP "dataciviclab-toolkit-quickstart"
py -m pip install -e ".[dev]"
py -m toolkit.cli.app run all -c project-example/dataset.yml
py -m toolkit.cli.app validate all -c project-example/dataset.yml
py -m toolkit.cli.app status --dataset project_example --year 2022 --config project-example/dataset.yml
```

Linux/macOS:

```bash
export TOOLKIT_OUTDIR="$(mktemp -d)/dataciviclab-toolkit-quickstart"
python -m pip install -e ".[dev]"
python -m toolkit.cli.app run all -c project-example/dataset.yml
python -m toolkit.cli.app validate all -c project-example/dataset.yml
python -m toolkit.cli.app status --dataset project_example --year 2022 --config project-example/dataset.yml
```

Validazione rapida della config prima di eseguire la pipeline:

```bash
toolkit run all --config dataset.yml --dry-run
```

Interpretazione errori config:

- `Config validation failed: output.<campo>: Extra inputs are not permitted` -> campo non supportato
Expand Down
65 changes: 65 additions & 0 deletions docs/conventions.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,68 @@ Non usarlo quando:
- RAW: `raw_validation.json`
- CLEAN: `_validate/clean_validation.json`
- MART: `_validate/mart_validation.json`

## Fonti pubbliche italiane — quirks noti

Pattern ricorrenti su CSV e XLSX da portali pubblici italiani. Da considerare
prima di scrivere `clean.sql` e `clean.read`.

### Encoding

La maggior parte dei portali PA produce file in `cp1252` (Windows-1252), non UTF-8.
Dichiarare sempre l'encoding esplicitamente:

```yaml
clean:
read:
encoding: cp1252
```

Se non dichiarato e il file contiene caratteri accentati, il run fallisce o
produce artefatti silenziosi.

### ZIP con XLSX annidati

Alcune fonti (es. MEF/Finanze, ISTAT) distribuiscono un archivio ZIP che
contiene uno o piu XLSX. Il toolkit non estrae ZIP automaticamente: il RAW
extractor deve essere configurato per gestire il pattern ZIP → file interno.

Verificare con `toolkit scout-url <url>` se la sorgente e` un ZIP prima di
configurare l'extractor.

### Schema instabile tra annualita

I CSV multi-anno di fonti come IRPEF, AIFA o SIOPE cambiano spesso:
- colonne aggiunte o rimosse tra un anno e l'altro
- nomi colonna con varianti ortografiche (maiuscolo/minuscolo, spazi vs underscore)
- righe di intestazione o footer aggiuntive in alcuni anni

Usare `toolkit inspect schema-diff --config dataset.yml --json` per confrontare
i segnali RAW tra anni prima di scrivere il `clean.sql`.

Per CSV con schema posizionale quasi stabile, usare `normalize_rows_to_columns: true`
(vedi sezione Positional Fixed Schema).

### Colonne con nomi impliciti o posizionali

Alcuni CSV non hanno header o hanno un header non standard (riga 2, merged cell
da XLSX). Dichiarare:

```yaml
clean:
read:
header: false
skip: 1 # righe da saltare prima dell'header reale
```

### Chiavi territoriali

Le chiavi geografiche nei dataset PA italiani non sono sempre ISTAT-standard:

- codici ISTAT comuni a 6 cifre vs 3+3 (provincia+comune)
- nomi comune con varianti storiche (fusioni, cambio denominazione)
- codici regione con offset legacy

Dichiarare i limiti noti nel `notes.md` del candidate e nel README di `analisi/`.
Non tentare di normalizzare le chiavi nel `clean.sql` senza documentare la
scelta esplicitamente.
2 changes: 2 additions & 0 deletions docs/feature-stability.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ Questa matrice serve a chiarire cosa il toolkit considera percorso canonico, cos
| artifact policy `minimal|standard|debug` | supported / advanced | tuning operativo |
| `legacy_aliases` | compatibility only | non promuovere nei repo nuovi |
| config legacy | compatibility only | usare `--strict-config` nei repo nuovi |
| `scout_url` | experimental | scouting rapido di un URL pubblico — non fa parte del workflow canonico |

Lettura equivalente a livello package:

- core runtime: `toolkit.raw`, `toolkit.clean`, `toolkit.mart`, `toolkit.cli` (`run`, `validate`, `status`, `inspect`)
Expand Down
42 changes: 18 additions & 24 deletions docs/publish_check.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,12 @@
# Publish Readiness Check

Publication blockers from the previous audit have been addressed:

- a root `LICENSE` file is present
- `pyproject.toml` now includes `license` and `authors` metadata
- the quickstart and publish notes no longer contain stale pre-release TODOs

## What is ready

- Core CLI flow exists and is usable from source with `python -m toolkit.cli.app` / `py -m toolkit.cli.app`.
- Core CLI flow exists and is usable after install with `toolkit`.
- Main commands expose help and non-zero failures on bad input:
- `py -m toolkit.cli.app --help`
- `py -m toolkit.cli.app run --help`
- `py -m toolkit.cli.app run all -c does-not-exist.yml`
- `toolkit --help`
- `toolkit run --help`
- `toolkit run all -c does-not-exist.yml`
- Root resolution is deterministic and documented:
- precedence is `dataset.yml root` -> `DCL_ROOT` -> `base_dir`
- no fallback to `cwd`
Expand Down Expand Up @@ -55,25 +49,25 @@ Publication blockers from the previous audit have been addressed:
Windows PowerShell:

```powershell
py -m pip install -e ".[dev]"
py -m ruff check .
py -m pytest -q
py -m toolkit.cli.app --help
py -m toolkit.cli.app run --help
py -m toolkit.cli.app run all -c project-example/dataset.yml
py -m toolkit.cli.app status --dataset project_example --year 2022 --config project-example/dataset.yml
pip install -e ".[dev]"
ruff check .
pytest -q
toolkit --help
toolkit run --help
toolkit run all -c project-example/dataset.yml
toolkit status --dataset project_example --year 2022 --config project-example/dataset.yml
git ls-files | Select-String -Pattern '(_smoke_out|_test_out|\.pytest_cache|\.ruff_cache|\.egg-info)'
```

Linux/macOS:

```bash
python -m pip install -e ".[dev]"
python -m ruff check .
python -m pytest -q
python -m toolkit.cli.app --help
python -m toolkit.cli.app run --help
python -m toolkit.cli.app run all -c project-example/dataset.yml
python -m toolkit.cli.app status --dataset project_example --year 2022 --config project-example/dataset.yml
pip install -e ".[dev]"
ruff check .
pytest -q
toolkit --help
toolkit run --help
toolkit run all -c project-example/dataset.yml
toolkit status --dataset project_example --year 2022 --config project-example/dataset.yml
git ls-files | grep -E '(_smoke_out|_test_out|\.pytest_cache|\.ruff_cache|\.egg-info)'
```
9 changes: 8 additions & 1 deletion docs/runtime-boundaries.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,18 @@ Sono le superfici che i repo dataset e il `project-template` dovrebbero consider
Queste aree restano supportate, ma non fanno parte del percorso canonico:

- `toolkit.profile`
- `toolkit.cross` — output multi-anno (`run cross_year`)
- `toolkit.cli.cmd_resume`
- `toolkit.cli.cmd_profile`
- esecuzione parziale `run raw|clean|mart`

Servono per recovery, diagnostica e casi sporchi, non come baseline per i repo nuovi.
Servono per recovery, diagnostica e output specializzati, non come baseline per i repo nuovi.

## Experimental

Funzionalita' presenti ma non ancora parte del contratto stabile:

- `toolkit.cli.cmd_scout_url` (`toolkit scout-url`) — scouting rapido di un URL pubblico

## Compatibility Only

Expand Down
4 changes: 1 addition & 3 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,7 @@
"test_registry.py",
}

COMPAT_TESTS = {
"test_deprecated_shims.py",
}
COMPAT_TESTS: set[str] = set()


def pytest_collection_modifyitems(items: list[pytest.Item]) -> None:
Expand Down
Loading