Servizio API per l'estrazione automatizzata di dati catastali dal portale SISTER (Servizi Integrati Telematici dell'Agenzia delle Entrate).
Disclaimer legale: questo progetto è uno strumento indipendente e non è affiliato, approvato o supportato dall'Agenzia delle Entrate. L'utente è l'unico responsabile del rispetto dei termini di servizio del portale SISTER e della normativa vigente. L'uso di automazione sul portale potrebbe violare i termini d'uso del servizio.
Compatibilità SPID: il login automatizzato funziona esclusivamente con il provider CIE Sign / Sielte ID. Altri provider SPID non sono supportati e richiederebbero modifiche al flusso di autenticazione in
utils.py.
Limitazioni note: alcune città presentano problemi con determinate mappe catastali o sezioni urbane. In questi casi l'estrazione potrebbe fallire o restituire dati incompleti. Il comportamento dipende dalla struttura dei dati sul portale SISTER, che varia da comune a comune.
- Panoramica
- Architettura
- Compatibilità SPID
- Installazione
- Configurazione
- Endpoint API
- Esempi d'uso
- Sviluppo locale
- Contribuire
- Licenza
Visura API fornisce accesso automatizzato ai dati catastali italiani tramite il portale SISTER. Usa l'automazione del browser (Playwright) e offre un'interfaccia REST per:
- Estrarre dati immobiliari (immobili) per specifiche particelle catastali
- Recuperare i titolari (intestati) di specifici immobili
- Estrarre le sezioni territoriali per tutte le province e comuni d'Italia
- Flusso a due fasi: prima estrae gli immobili, poi gli intestati per immobili specifici
- Filtro automatico: esclude gli immobili con partita "Soppressa"
- Gestione sessione: mantiene la sessione autenticata con il portale SISTER
- Coda di elaborazione: gestisce richieste multiple senza sovraccaricare il portale
- Ri-autenticazione automatica: alla scadenza della sessione
- Distribuzione con Docker: pronto per il deploy containerizzato
┌─────────────────┐ ┌─────────────────┐
│ Applicazione │───▶│ FastAPI │
│ client │ │ (main.py) │
└─────────────────┘ └─────────────────┘
│
▼
┌─────────────────┐
│ Playwright │
│ (automazione │
│ browser) │
└─────────────────┘
│
▼
┌─────────────────┐
│ Portale │
│ SISTER │
└─────────────────┘
| File | Descrizione |
|---|---|
main.py |
Applicazione FastAPI con endpoint REST e gestione della coda |
utils.py |
Funzioni di automazione del browser con Playwright |
docker-compose.yaml |
Orchestrazione dei container |
Importante: attualmente il login automatizzato è implementato esclusivamente per il provider SPID CIE Sign / Sielte ID. Se utilizzi un altro provider SPID, dovrai adattare il flusso di autenticazione in
utils.py(funzionelogin()).
- Python 3.11+
- Docker e Docker Compose (per il deploy)
- Credenziali valide per il portale SISTER (SPID tramite CIE Sign / Sielte ID)
git clone https://github.com/menimenocchio/visura-api.git
cd visura-api
# Configura le variabili d'ambiente
cp .env.example .env
# Modifica .env con le tue credenziali
# Avvia il servizio
docker-compose up -d
# Verifica che il servizio sia attivo
curl http://localhost:8000/healthgit clone https://github.com/menimenocchio/visura-api.git
cd visura-api
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
playwright install chromium
cp .env.example .env
# Modifica .env con le tue credenziali
uvicorn main:app --host 0.0.0.0 --port 8000Crea un file .env nella cartella del progetto (vedi .env.example):
# Credenziali SPID / Agenzia delle Entrate
ADE_USERNAME=il_tuo_codice_fiscale
ADE_PASSWORD=la_tua_password
# Configurazione opzionale
LOG_LEVEL=INFO
CONCURRENT_WORKERS=3GET /health — Verifica lo stato del servizio
{
"status": "healthy",
"authenticated": true,
"queue_size": 0
}POST /visura — Estrae gli immobili per una particella catastale
// Richiesta
{
"provincia": "Trieste",
"comune": "TRIESTE",
"foglio": "9",
"particella": "166",
"sezione": null,
"tipo_catasto": "F" // "F" = Fabbricati, "T" = Terreni (opzionale, se omesso esegue entrambi)
}
// Risposta
{
"request_ids": ["req_F_1693747200000"],
"tipos_catasto": ["F"],
"status": "queued",
"message": "Richieste aggiunte alla coda per TRIESTE F.9 P.166"
}GET /visura/{request_id} — Recupera i risultati di una richiesta
{
"request_id": "req_F_1693747200000",
"tipo_catasto": "F",
"status": "completed",
"data": {
"immobili": [
{
"Foglio": "9",
"Particella": "166",
"Sub": "1",
"Categoria": "A/2",
"Indirizzo": "Via Roma 123",
"Rendita": "500.00"
}
],
"intestati": []
},
"timestamp": "2026-03-15T10:30:00"
}POST /visura/intestati — Estrae gli intestati di un immobile specifico
// Richiesta
{
"provincia": "Trieste",
"comune": "TRIESTE",
"foglio": "9",
"particella": "166",
"tipo_catasto": "F",
"subalterno": "1" // Obbligatorio per Fabbricati
}
// Risposta
{
"request_id": "intestati_F_1_1693747300000",
"tipo_catasto": "F",
"subalterno": "1",
"status": "queued",
"queue_position": 1
}POST /sezioni/extract — Avvia l'estrazione delle sezioni per tutte le province
// Richiesta
{
"tipo_catasto": "T",
"max_province": 200
}
// Risposta
{
"status": "success",
"message": "Estrazione completata per tipo catasto T",
"total_extracted": 42000,
"tipo_catasto": "T",
"sezioni": [...]
}| Endpoint | Metodo | Descrizione |
|---|---|---|
/shutdown |
POST | Shutdown controllato con logout dal portale |
# 1. Avvia l'estrazione dei fabbricati per una particella
curl -X POST "http://localhost:8000/visura" \
-H "Content-Type: application/json" \
-d '{"provincia": "Trieste", "comune": "TRIESTE", "foglio": "9", "particella": "166", "tipo_catasto": "F"}'
# 2. Controlla i risultati (attendi qualche secondo)
curl "http://localhost:8000/visura/req_F_1693747200000"
# 3. Estrai gli intestati per un immobile specifico
curl -X POST "http://localhost:8000/visura/intestati" \
-H "Content-Type: application/json" \
-d '{"provincia": "Trieste", "comune": "TRIESTE", "foglio": "9", "particella": "166", "tipo_catasto": "F", "subalterno": "1"}'import requests
import time
class ClientVisura:
def __init__(self, url_base="http://localhost:8000"):
self.url_base = url_base
def estrai_immobili(self, provincia, comune, foglio, particella, sezione=None, tipo_catasto="F"):
"""Fase 1: Estrae gli immobili di una particella"""
dati = {
"provincia": provincia,
"comune": comune,
"foglio": foglio,
"particella": particella,
"tipo_catasto": tipo_catasto
}
if sezione:
dati["sezione"] = sezione
risposta = requests.post(f"{self.url_base}/visura", json=dati)
return risposta.json()
def attendi_risultati(self, request_id, attesa_max=300):
"""Attende il completamento di una richiesta"""
inizio = time.time()
while time.time() - inizio < attesa_max:
risposta = requests.get(f"{self.url_base}/visura/{request_id}")
risultato = risposta.json()
if risultato["status"] in ["completed", "error"]:
return risultato
time.sleep(5)
raise TimeoutError(f"Richiesta {request_id} non completata entro {attesa_max} secondi")
def estrai_intestati(self, provincia, comune, foglio, particella, tipo_catasto, subalterno=None, sezione=None):
"""Fase 2: Estrae gli intestati di un immobile"""
dati = {
"provincia": provincia,
"comune": comune,
"foglio": foglio,
"particella": particella,
"tipo_catasto": tipo_catasto
}
if subalterno:
dati["subalterno"] = subalterno
if sezione:
dati["sezione"] = sezione
risposta = requests.post(f"{self.url_base}/visura/intestati", json=dati)
return risposta.json()
# Esempio d'uso
client = ClientVisura()
# Estrai i fabbricati
estrazione = client.estrai_immobili("Trieste", "TRIESTE", "9", "166", tipo_catasto="F")
request_id = estrazione["request_ids"][0]
# Attendi i risultati
risultati = client.attendi_risultati(request_id)
print(f"Trovati {len(risultati['data']['immobili'])} immobili")
# Estrai gli intestati del primo immobile
intestati = client.estrai_intestati("Trieste", "TRIESTE", "9", "166", "F", subalterno="1")python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
pip install pytest pytest-cov black ruff # dipendenze di sviluppo
playwright install chromiumpython -m pytest test_*.py -vblack . # formattazione automatica
ruff check . # controllo linting# Avvia il servizio
docker-compose up --build
# Visualizza i log
docker-compose logs -f visure-serviceI log vengono scritti sia su console che su file (logs/visura.log).
Livelli disponibili: DEBUG, INFO, WARNING, ERROR
# Abilita i log dettagliati
export LOG_LEVEL=DEBUG- Il portale SISTER ha limiti interni di frequenza delle richieste
- Il servizio accoda le richieste per non sovraccaricare il portale
- Tempo tipico di elaborazione: 30-60 secondi per richiesta
- Requisiti minimi: 2 GB RAM, 2 core CPU, connessione stabile
| Problema | Soluzione |
|---|---|
| Il servizio non si avvia | Controlla i log: docker-compose logs visure-service |
| Autenticazione fallita | Verifica le credenziali nel file .env |
| Risposte lente | Controlla la dimensione della coda: GET /health |
| Sessione scaduta | Il servizio si ri-autentica automaticamente |
Leggi CONTRIBUTING.md per le linee guida su come contribuire al progetto.
Questo progetto è distribuito sotto la licenza GNU General Public License v3.0. Vedi il file LICENSE per i dettagli.
Ultimo aggiornamento: marzo 2026