onData homepage

Guida all'uso delle API REST di ISTAT

Per domande e/o suggerimenti su questa guida, è possibile creare una nuova issue qui


Perché questa guida

L’Istituto nazionale di statistica (ISTAT) consente di accedere ai dati del proprio warehouse (http://dati.istat.it/) in molte modalità. L’accesso via API REST è poco noto, molto comodo, ma poco documentato.
Nella pagina ufficiale dei loro web service e nelle guide presenti non c’è alcuna documentazione dedicata.
C’è un riferimento alle “RESTful API” in questa pagina http://sdmx.istat.it/SDMXWS/.

La mancanza di informazioni in merito e le opportunità che vengono offerte, ci hanno spinto a scrivere questa guida non esaustiva, che descrive queste modalità di accesso.

Se vuoi proporre una modifica/integrazione/correzione a questa guida, questo è il file e questo è il repository che ospita il progetto.

Come interrogare le API

L’URL base di accesso è http://sdmx.istat.it/SDMXWS/rest/. Da questo si possono interrogare i metadati e i dati, con una chiamata HTTP in GET. Quindi pressoché da qualsiasi client.

Sono dati esposti secondo lo standard SDMX.

Che strumenti usare

Vista la modalità di accesso, basta un browser, wget, cURL e/o qualsiasi modulo/funzione che in un linguaggio di scripting consenta l’accesso HTTP in GET.

In alternativa è possibile usare un software di API development e testing, ad esempio Postman. Si rimanda al capitolo dedicato: Come interrogare le API con Postman.

Accedere ai metadati

Questa è la struttura dell’URL per accedere ai metadati:

http://sdmx.istat.it/SDMXWS/rest/resource/agencyID/resourceID/version/itemID?queryStringParameters

Alcune note:

Un esempio è quello che restituisce i dataflow, ovvero l’elenco dei flussi di dati interrogabili.
Per averlo restituito l’URL è http://sdmx.istat.it/SDMXWS/rest/dataflow/IT1.

Si ottiene in risposta un file XML come questo, che all’interno contiene dei blocchi come quello sottostante, in cui ai dati su “Incidenti, morti e feriti - comuni” è associato l’id 41_983.

<structure:Dataflow id="41_983" urn="urn:sdmx:org.sdmx.infomodel.datastructure.Dataflow=IT1:41_983(1.0)" agencyID="IT1" version="1.0" isFinal="false">
  <common:Name xml:lang="it">Incidenti, morti e feriti - comuni</common:Name>
  <common:Name xml:lang="en">Road accidents, killed and injured - municipalities</common:Name>
  <structure:Structure>
    <Ref id="DCIS_INCIDMORFER_COM" version="1.0" agencyID="IT1" package="datastructure" class="DataStructure" />
  </structure:Structure>
</structure:Dataflow>

L’elenco ad oggi (3 maggio 2020) dei dataset interrogabili è composto da circa 450 elementi, visualizzabili in questo file CSV.

Accedere ai dati

Questa è la struttura dell’URL per accedere ai dati:

http://sdmx.istat.it/SDMXWS/rest/data/flowRef/key/providerRef?queryStringParameters

Alcune note:

Visto che l’unico parametro obbligatorio è l’ID del dataflow, per scaricare quello di sopra sugli incidenti stradali l’URL sarà (OCCHIO CHE SUL BROWSER pesa, sono 53 MB di file XML, meglio non fare click e leggerlo soltanto) http://sdmx.istat.it/SDMXWS/rest/data/41_983.

torna su

Qualche esempio

Per gli esempi sottostanti verrà usata l’utility cURL, in quanto disponibile e utilizzabile su qualsiasi sistema operativo.

NOTA BENE: scaricando i file in blocco, senza alcun filtro, si ottengono file di grandi dimensioni. Pertanto - ove possibile - è consigliato applicare i filtri adeguati ai propri interessi, sia per non avere informazioni ridondanti, che per non stressare il servizio di ISTAT.

Scaricare i dati in blocco

Il formato di output di default è l’XML.

curl -kL "http://sdmx.istat.it/SDMXWS/rest/data/41_983" >./41_983.xml

Cambiare formato di output

Basta impostare in modo adeguato l’header HTTP.

In CSV:

curl -kL -H "Accept: application/vnd.sdmx.data+csv;version=1.0.0" "http://sdmx.istat.it/SDMXWS/rest/data/41_983" >./41_983.csv

In JSON:

curl -kL -H "Accept: application/json" "http://sdmx.istat.it/SDMXWS/rest/data/41_983" >./41_983.json

Applicare dei filtri

Per applicare dei filtri è necessario conoscere quale sia lo schema dati del dataflow che si vuole interrogare. Questo è descritto nella risorsa di metadati denominata datastructure, che si può interrogare per ID. Ma qual è ad esempio l’ID del dataset sugli incidenti stradali, presente in datastructure?
È scritto nel dataflow. Si riporta nuovamente quello di sopra e si legge che l’ID di riferimento presente in datastructure è DCIS_INCIDMORFER_COM.

<structure:Dataflow id="41_983" urn="urn:sdmx:org.sdmx.infomodel.datastructure.Dataflow=IT1:41_983(1.0)" agencyID="IT1" version="1.0" isFinal="false">
  <common:Name xml:lang="it">Incidenti, morti e feriti - comuni</common:Name>
  <common:Name xml:lang="en">Road accidents, killed and injured - municipalities</common:Name>
  <structure:Structure>
    <Ref id="DCIS_INCIDMORFER_COM" version="1.0" agencyID="IT1" package="datastructure" class="DataStructure" />
  </structure:Structure>
</structure:Dataflow>

torna su

Schema dati

Per leggere lo schema dati di DCIS_INCIDMORFER_COM, si potrà lanciare questa chiamata:

curl -kL "http://sdmx.istat.it/SDMXWS/rest/datastructure/IT1/DCIS_INCIDMORFER_COM/" >./DCIS_INCIDMORFER_COM.xml

Nel file XML di output c’è il tag structure:DimensionList (vedi sotto), che contiene la lista delle dimensioni, ovvero lo schema dati del dataset.
In questo elenco le dimensioni con id FREQ, ESITO, ITTER107,TIPO_DATO e SELECT_TIME.

<structure:DimensionList id="DimensionDescriptor" urn="urn:sdmx:org.sdmx.infomodel.datastructure.DimensionDescriptor=IT1:DCIS_INCIDMORFER_COM(1.0).DimensionDescriptor">
  <structure:Dimension id="FREQ" urn="urn:sdmx:org.sdmx.infomodel.datastructure.Dimension=IT1:DCIS_INCIDMORFER_COM(1.0).FREQ" position="1">
    <structure:ConceptIdentity>
      <Ref id="FREQ" maintainableParentID="CROSS_DOMAIN" maintainableParentVersion="4.2" agencyID="IT1" package="conceptscheme" class="Concept" />
    </structure:ConceptIdentity>
    <structure:LocalRepresentation>
      <structure:Enumeration>
        <Ref id="CL_FREQ" version="1.0" agencyID="IT1" package="codelist" class="Codelist" />
      </structure:Enumeration>
    </structure:LocalRepresentation>
  </structure:Dimension>
  <structure:Dimension id="ESITO" urn="urn:sdmx:org.sdmx.infomodel.datastructure.Dimension=IT1:DCIS_INCIDMORFER_COM(1.0).ESITO" position="2">
    <structure:ConceptIdentity>
      <Ref id="ESITO" maintainableParentID="VARIAB_ALL" maintainableParentVersion="18.3" agencyID="IT1" package="conceptscheme" class="Concept" />
    </structure:ConceptIdentity>
    <structure:LocalRepresentation>
      <structure:Enumeration>
        <Ref id="CL_ESITO" version="1.0" agencyID="IT1" package="codelist" class="Codelist" />
      </structure:Enumeration>
    </structure:LocalRepresentation>
  </structure:Dimension>
  <structure:Dimension id="ITTER107" urn="urn:sdmx:org.sdmx.infomodel.datastructure.Dimension=IT1:DCIS_INCIDMORFER_COM(1.0).ITTER107" position="3">
    <structure:ConceptIdentity>
      <Ref id="ITTER107" maintainableParentID="VARIAB_ALL" maintainableParentVersion="18.3" agencyID="IT1" package="conceptscheme" class="Concept" />
    </structure:ConceptIdentity>
    <structure:LocalRepresentation>
      <structure:Enumeration>
        <Ref id="CL_ITTER107" version="4.6" agencyID="IT1" package="codelist" class="Codelist" />
      </structure:Enumeration>
    </structure:LocalRepresentation>
  </structure:Dimension>
  <structure:Dimension id="TIPO_DATO" urn="urn:sdmx:org.sdmx.infomodel.datastructure.Dimension=IT1:DCIS_INCIDMORFER_COM(1.0).TIPO_DATO" position="4">
    <structure:ConceptIdentity>
      <Ref id="TIPO_DATO" maintainableParentID="CROSS_DOMAIN" maintainableParentVersion="4.2" agencyID="IT1" package="conceptscheme" class="Concept" />
    </structure:ConceptIdentity>
    <structure:LocalRepresentation>
      <structure:Enumeration>
        <Ref id="CL_TIPO_DATO22" version="1.0" agencyID="IT1" package="codelist" class="Codelist" />
      </structure:Enumeration>
    </structure:LocalRepresentation>
  </structure:Dimension>
  <structure:TimeDimension id="TIME_PERIOD" urn="urn:sdmx:org.sdmx.infomodel.datastructure.TimeDimension=IT1:DCIS_INCIDMORFER_COM(1.0).TIME_PERIOD" position="5">
    <structure:ConceptIdentity>
      <Ref id="SELECT_TIME" maintainableParentID="CROSS_DOMAIN" maintainableParentVersion="4.2" agencyID="IT1" package="conceptscheme" class="Concept" />
    </structure:ConceptIdentity>
    <structure:LocalRepresentation>
      <structure:TextFormat textType="ObservationalTimePeriod" />
    </structure:LocalRepresentation>
  </structure:TimeDimension>
</structure:DimensionList>

Ma qual è il significato di FREQ, ESITO, ITTER107,TIPO_DATO e SELECT_TIME?

La risposta a questa domanda ce la dà la risorsa di metadati - il package - denominata codelist. Si può interrogare sempre per ID, ma bisogna conoscere l’ID dei vari campi, che è scritto nel file XML di sopra.
Ad esempio in corrispondenza del campo FREQ si legge <Ref id="CL_FREQ" version="1.0" agencyID="IT1" package="codelist" class="Codelist" />, ovvero che l’ID corrispondente in codelist è CL_FREQ. L’URL da lanciare per avere le informazioi su questo campo, sarà un altro URL per interrogare metadati e in particolare http://sdmx.istat.it/SDMXWS/rest/codelist/IT1/CL_FREQ.

In output un file XML, dove si legge che si tratta della “Frequenza”. Nell’XML si leggono anche i valori possibili per questa dimensione, che per CL_FREQ corrispondono alle sottostanti coppie di ID e valore.

ID Descrizione
A annuale
B business (non supportato)
D giornaliero
E event (non supportato)
H semestrale
M mensile
Q trimestrale
W settimanale

NOTA BENE: queste coppie sono quelle genericamente applicabili per la “Frequenza”, non è però detto che tutti i valori siano disponibili per un determinato dataflow (vedi paragrafo successivo), che potrebbe ad esempio esporre soltanto quella annuale.

torna su

Quali codici/valori sono disponibili per filtrare un determinato dataflow per dimensione

Per ricavarli è possibile sfruttare la risorsa availableconstraint, che in termini SQL è un SELECT DISTINCT sulle dimensioni.

Per conoscere ad esempio quelle del dataflow 41_983 l’URL è:

http://sdmx.istat.it/SDMXWS/rest/availableconstraint/41_983

In output un file XML come questo, in cui ad esempio si legge che per questo specificico dataflow il valore disponibile per la dimensione FREQ (Frequenza) è A, ovvero quella annuale.

<common:KeyValue id="FREQ">
  <common:Value>A</common:Value>
</common:KeyValue>

torna su

Costruire l’URL per filtrare un dataflow, fare una query per attributo

Una query per attributo/i, ne deve elencare i valori nell’URL secondo questo schema:

http://sdmx.istat.it/SDMXWS/rest/data/flowRef/valoreCampo1.valoreCampo2.valoreCampo3/

Questo di sopra è un caso di uno schema dati con tre campi; i valori vanno separati con un . (punto). Se il valore non è specificato, nessun filtro per quel campo/dimensione sarà applicato. Quindi un URL come

http://sdmx.istat.it/SDMXWS/rest/data/flowRef/../

equivale a non applicare alcun filtro.

Per il dataflow che stiamo usando per questa guida, un esempio potrebbe essere quello di tutti gli incidenti con feriti (valore F). Il campo è ESITO, che nello schema dati è il secondo campo. Qui i campi/dimensioni a disposizione sono 5, quindi per applicare questo filtro dovremo aggiungere nell’URL la stringa .F... (5 campi, di cui il secondo valorizzato e gli altri vuoti) e lanciare:

curl -kL -H "Accept: application/vnd.sdmx.data+csv;version=1.0.0" "http://sdmx.istat.it/SDMXWS/rest/data/41_983/.F..." >filtro_esempio01.csv

Si otterrà un CSV con filtrati 145.000 record, sul totale di 435.000.

Tra i campi anche ITTER107 (è il terzo), che è quello del codice comunale ISTAT. Se voglio quindi ottenere i dati sugli incidenti stradali con feriti, nella città di Palermo (codice comunale ISTAT 082053) - filtro .F.082053.. - il comando sarà:

curl -kL -H "Accept: application/vnd.sdmx.data+csv;version=1.0.0" "http://sdmx.istat.it/SDMXWS/rest/data/41_983/.F.082053.." >filtro_esempio02.csv

Sono 18 record, uno per ogni anno (questo dataset espone dati aggregati per anno dal 2001 al 2018).
Qui sotto un grafico d’esempio generato proprio con i dati di output di questa query.


Si possono inserire più valori per lo stesso campo, separandoli con il carattere +. Se ad esempio si vogliono aggiungere anche gli incidenti con feriti, del comune di Bari (codice ISTAT 072006) - filtro .F.082053+072006.. - il comando sarà:

curl -kL -H "Accept: application/vnd.sdmx.data+csv;version=1.0.0" "http://sdmx.istat.it/SDMXWS/rest/data/41_983/.F.082053+072006.." >filtro_esempio03.csv

Il ultimo una query i cui aggiungere un queryStringParameters, in particolare startPeriod, ovvero impostare il periodo a partire dal quale si vogliono dati. Si possono usare date in formato ISO8601 e se quindi si vogliono i dati a partire dall’anno 2015, il comando sarà:

curl -kL -H "Accept: application/vnd.sdmx.data+csv;version=1.0.0" "http://sdmx.istat.it/SDMXWS/rest/data/41_983/?startPeriod=2015" >./filtro_esempio04.csv

Come interrogare le API con Postman

Un’altra modalità per interrogare le API SDMX di Istat potrebbe essere quella di usare Postman, un software di API development e testing.

Vincenzo Sciascia ha scritto una guida dedicata (grazie!), che trovate in una lunga e ricca sezione dedicata.

image

Altre banche dati ISTAT accessibili allo stesso modo

L’Istat - come è possibile leggere qui - espone nelle stesse modalità anche queste altre 3 banche dati:

A seguire, come esempio, gli end-point REST dell’elenco dei dataflow (le tabelle esposte) di ciascuna:

Note

Questa guida è stata redatta leggendo la documentazione - non di ISTAT - presente in altri siti che documentano l’accesso REST a servizi SDMX. Il primo da cui siamo partiti è la guida delle API di accesso ai dati de l’“Organisation for Economic Co-operation and Development” (OECD).
Se userete queste API, l’invito è quello di approfondire tramite una o più delle risorse in sitografia.

Abbiamo fatto pochi test e verifiche, quindi non sappiamo se tutto funziona bene.

In ultimo, la cosa più importante: chiediamo a ISTAT di documentare l’accesso alle loro API in modalità RESTful.

Sostieni le nostre attività

Se vuoi sostenere le nostre attività, puoi farlo donando il tuo 5x1000.

Sitografia

torna su

Cheatsheet di riferimento

Lo SDMX Technical Standards Working Group ha creato un cheatsheet molto leggibile e didattico, da cui abbiamo preso fortemente spunto. Lo riportiamo a seguire.
NOTA BENE: alcune delle opzioni di sotto potrebbero essere non attive presso l’endpoint di ISTAT.

Structural metadata queries:
http://sdmx.istat.it/SDMXWS/rest/resource/agencyID/resourceID/version/itemID?queryStringParameters

Path parameter Description Default
resource (mandatory) The type of metadata to be returned. Values: datastructure, metadatastructure, categoryscheme, conceptscheme, codelist, hierarchicalcodelist, organisationscheme, agencyscheme, dataproviderscheme, dataconsumerscheme, organisationunitscheme, dataflow, metadataflow, reportingtaxonomy, provisionagreement, structureset, process, categorisation, contentconstraint, attachmentconstraint, actualconstraint, allowedconstraint, structure  
agencyID Agency maintaining the artefact (e.g.: SDMX) all
resourceID Artefact ID (e.g.: CL_FREQ) all
version Arterfact version (e.g.: 1.0) latest
itemID ID of the item (for item schemes) or hierarchy (for hierarchical codelists) to be returned. all
detail Desired amount of information. Values: allstubs, referencestubs, allcompletestubs, referencecompletestubs, referencepartial, full. full
references References to be returned with the artefact. Values: none, parents, parentsandsiblings, children, descendants, all, any type of resource. none

Data queries:
http://sdmx.istat.it/SDMXWS/rest/data/flowRef/key/providerRef?queryStringParameters

Path parameter Description Default
flowRef (mandatory) Dataflow ref (e.g. 41_983, etc.)  
key Key of the series to be returned (e.g: D.NOK.EUR.SP00.A). Wildcarding (e.g: D..EUR.SP00.A) and OR (e.g: D.NOK+RUB.EUR.SP00.A) supported. all
providerRef Data provider (e.g.: IT1) all
startPeriod Start period (inclusive). ISO8601 (e.g. 2014-01) or SDMX reporting period (e.g. 2014-Q3).  
endPeriod End period (inclusive). ISO8601 (e.g. 2014-01-01) or SDMX reporting period (e.g. 2014-W53).  
updatedAfter Last time the query was performed. Used to retrieve deltas. Must be percent-encoded (e.g.: 2009-05-15T14%3A15%3A00%2B01%3A00)  
firstNObservations Maximum number of observations starting from the first observation  
lastNObservations Maximum number of observations counting back from the most recent observation  
dimensionAtObservation Id fof the dimension attached at the observation level TIME_PERIOD
detail Desired amount of information to be returned. Values: full, dataonly, serieskeysonly, nodata full
includeHistory Whether to return vintages false

Useful HTTP headers

Headers Description
If-Modified-Since Get the data only if something has changed
Accept Select the desired format
Accept-Encoding Compress the response

Supported formats

Formats Syntax
SDMX-ML Generic Data application/vnd.sdmx.genericdata+xml;version=2.1
SDMX-ML StructureSpecific Data application/vnd.sdmx.structurespecificdata+xml;version=2.1
SDMX-JSON Data application/vnd.sdmx.data+json;version=1.0.0
SDMX-CSV Data application/vnd.sdmx.data+csv;version=1.0.0
SDMX-ML Structure application/vnd.sdmx.structure+xml;version=2.1
SDMX-JSON Structure application/vnd.sdmx.structure+json;version=1.0.0
SDMX-ML Schemas application/vnd.sdmx.schema+xml;version=2.1
SDMX-ML Generic Metadata application/vnd.sdmx.genericmetadata+xml;version=2.1
SDMX-ML StructureSpecific Meta application/vnd.sdmx.structurespecificmetadata+xml;version=2.1

Period formats

Period Format
Daily/Business YYYY-MM-DD
Weekly YYYY-W[01-53]
Monthly YYYY-MM
Quarterly YYYY-Q[1-4]
Semi-annual YYYY-S[1-2]
Annual YYYY

Useful response codes

Code Description
200 (OK) Life is good
304 (No change) No change since the timestamp supplied in the If-Modified-Since header
400 (Syntax error) Your query checking you must
401 (Login needed) Only available on a need to know basis
403 (Semantic error) The syntax of the query is OK but it makes no sense anyway. Tolerated only on April Fools
404 (Not found) No results. Mostly harmless, especially if you used updatedAfter
406 (Invalid format) Not a supported format. No worries, SDMX is all you need
413 (Results too large) You know greed is a sin, right?
414 (URI too long) Write short sentences
500 (Server error) Someone somewhere is having a bad day
501 (Not implemented) Feature coming soon in a web service near you
503 (Unavailable) Try again later.

Licenza Creative Commons
Questa guida è distribuita con Licenza Creative Commons Attribuzione 4.0 Internazionale.

torna su

Webinar dedicato

Il 14 maggio 2020 è stato organizzato un webinar dal titolo Le API sui dati statistici di Istat e il progetto SDMX, con Fabio Spagnuolo (Istat), Vincenzo Patruno (Istat e vicepresidente di onData) e Andrea Borruso (presidente di onData).

Le slide https://docs.google.com/presentation/d/1pwGvIpynD6NbPyyodS7a_nUiUoAcwwaLc7H-NlVpnpk/present#slide=id.p1