IIoT REST APIs

L'unione tra anni di esperienza e la mia passione per la programmazione.

Introduzione

Ciao a tutti!
Vista la mia grande curiosità per lo sviluppo back-end con Python, ho voluto unire la mia ultra-settennale esperienza lavorativa nel mondo dell’IIoT con la passione per la programmazione, realizzando un software che potesse essere al contempo utile e mi desse la possibilità di approfondire in maniera pratica quanto ho studiato negli ultimi mesi.

Come obiettivo di questo progetto, ho tenuto a mente il fenomeno della “digital transformation”, utilizzando delle tecnologie modulari e più orientate ai microservizi piuttosto che altri framework maggiormente conosciuti e più articolati, attraverso i quali sono comunque riuscito a realizzare quanto preventivato.

Tenendo a mente questo “docet” con il quale sviluppare il progetto, con poco più di 600 righe di codice distribuite nei vari scripts (tra i quali ci sono anche files contenenti solamente strutture dati e non algoritmi), ho realizzato un software per il campionamento, la storicizzazione, l’interrogazione e l’analisi dati di un numero finito di misure analogiche in un ambiente di produzione.

Struttura del progetto

Il progetto è composto principalmente da due “moduli”, ognuno dei quali ha un ruolo ben preciso:

Le principali tecnologie utilizzate per i vari moduli del progetto sono:



In entrambi i moduli, viene utilizzato SQLAlchemy come ORM.

La struttura logica del software è così rappresentata:

Logica di funzionamento dei moduli

Il funzionamento dei moduli del progetto è illustrato di seguito:

Ogni endpoint configurato ritorna una response in formato JSON (tranne per un endpoint il quale ritorna un’immagine), in modo tale da essere facilmente human-readable, ed essendo un formato ampiamente utilizzato nel mondo del web development, può essere facilmente interpretato dalla maggior parte dei framework front-end e da svariati altri tools:

Configurazione degli endpoint

Gli endpoint configurati sono cinque (compreso l’endpoint “root” e "docs"), e sono:

Di seguito è possibile osservare nel dettaglio le funzionalità dei vari endpoints attraverso la documentazione interattiva.

Tags endpoint

Figura 1 - Panoramica dell'endpoint "tags" relativa al metodo "GET"


Figura 2 - Panoramica dell'endpoint "tags" relativa al metodo "GET" con l'applicazione del filtro "name_like"


Figura 3 - Panoramica dell'endpoint "tags" relativa al metodo "GET" con l'applicazione dei filtri "name_like" e  "description_like"


Figura 4 - Panoramica dell'endpoint "tags" relativa al metodo "POST


Data endpoint

Figura 1 - Panoramica dell'endpoint "data" relativa al metodo "GET"


Figura 2 - Panoramica dell'endpoint "data" relativa al metodo "GET" con l'applicazione dei filtri "period" e "name_like" (continua in Figura 3)


Figura 3 - Panoramica dell'endpoint "data" relativa al metodo "GET" con l'applicazione dei filtri "period" e "name_like"


Chart endpoint

Figura 1 - Panoramica dell'endpoint "chart" relativa al metodo "GET"


Figura 2 - Panoramica dell'endpoint "chart" relativa al metodo "GET" con l'applicazione dei filtri "tag_name" e "period" (continua in Figura 3)


Figura 3 - Panoramica dell'endpoint "chart" relativa al metodo "GET" con l'applicazione dei filtri "tag_name" e "period" 


Codice

Come accennato nell'introduzione, ho sviluppato il progetto utilizzando il linguaggio di programmazione Python, un linguaggio semplice ma potente con un ampio bacino di campi di applicazione (machine learning, data analysis, web development, data science, scripting...).
L'uso della tipizzazione nel codice, unito alla scrittura dei commenti e delle docstrings, ha reso lo stesso più chiaro e developer-friendly, oltre che a rendere possibile la creazione automatica della documentazione delle API grazie a OpenAPI.

Grazie alla struttura modulare degli scripts, ho avuto la possibilità di scrivere svariate parti di codice una volta sola, potendolo così riutilizzarlo in più parti del progetto, evitando così di avere codice "boilerplate".

Nel corso dello sviluppo del progetto ho utilizzato gran parte delle mie conoscenze applicate già nel mondo del lavoro, specialmente riguardo la gestione dei dati attraverso un database, e le espressioni regolari, con le quali ho avuto modo di realizzare la maggior parte dei controlli di validazione dell'input degli utenti.

Con l'approccio al Continuous Integration, ho avuto modo di monitorare il comportamento delle varie parti dell'applicazione, intervenendo con criterio dove notavo un'anomalia, anche grazie all'ausilio di librerie per il logging delle informazioni.
Una volta risolte le anomalie e testate in maniera diretta, le modifiche venivano sincronizzate con un repository su GitHub attraverso l'utilizzo di git.

Grazie a tools di linting come ruff, ho avuto la possibilità di individuare degli errori critici e degli warning durante lo sviluppo del codice, rendendolo più funzionale e quanto più conforme alle PEP 8.

Figura 1 - Funzione per la validazione del periodo temporale inserito dall'utente

Figura 2 - Metodo "GET" dell'endpoint "data", con l'utilizzo dell'approccio "ORM" di SQLAlchemy

Figura 3 - Definizione dei DTOs (Data Transfer Objects), utilizzati da FastAPI e Pydantic

Figura 4 - Utilizzo di matplotlib per la creazione dei grafici storici

Figura 5 - Utilizzo di ruff per il linting del codice

Considerazioni

Sono estremamente soddisfatto di aver portato a compimento la prima versione di questo piccolo progetto, poiché ho avuto modo di imparare nuovi aspetti della programmazione, coltivandoli sull'esperienza acquisita finora.
Il progetto potrebbe essere espanso ulteriormente, poiché attualmente la lettura dei dati viene effettuata da un solo device, ma con una piccola integrazione nel codice del collettore, i dati potrebbero facilmente essere campionati da più devices, purché questi siano raggiungibili via Ethernet.

Per completezza, data la mia curiosità e il mio recente studio riguardo i "Docker containers", avrei voluto containerizzare l'intera applicazione, rendendola a tutti gli effetti un pacchetto di micro-servizi, ma per via del fatto che il PC sul quale ho sviluppato l'applicazione risulta avere Windows Server 2016 come sistema operativo, avrei dovuto installare la versione Enterprise di Docker Desktop.

Un'ulteriore integrazione che mi piacerebbe davvero tanto fare è quella di realizzare il front-end dell'applicazione, utilizzando un framework semplice e robusto, dandole così un aspetto più user-friendly.

Il motivo principale che mi ha spinto a realizzare quest'applicazione è stato quello di creare da zero un progetto che potesse conciliare con i miei anni di esperienza nel mondo IIoT con la grande passione della programmazione e dello sviluppo back-end.

Se sei arrivato fin qui, ti ringrazio immensamente per la lettura, e nel caso in cui avessi dei consigli da darmi, ti invito a contattarmi attraverso i miei social network o attraverso il modulo contatti.