Config file JSON in Python

In questo tutorial vediamo cos’è e come utilizzare un config file JSON in Python, un file di configurazione che può semplificarci la vita.

Una delle cose che ho imparato programmando in Python è che spesso ciò che sembra più semplice e veloce sul momento spesso può rivelarsi un’arma a doppio taglio.

Oggi vediamo una di quelle pratiche che sembrerebbe macchinosa e un po’ inutile, ma che in realtà può spesso salvarci la vita. O almeno, se non la vita, tempo e nervi.

Stiamo parlando di un config file JSON, ovvero un file di configurazione. Vediamo allora cos’è e come possiamo usarlo nel nostro codice Python.

INDICE

  1. Cos’è un config file
  2. Come usare un config file nel codice

1. COS’E’ UN CONFIG FILE

Un config file, o file di configurazione, è un file in cui possiamo inserire delle specifiche da far leggere a Python senza dover andare a toccare il codice.

Spesso siamo abituati, soprattutto all’inizio, a considerare il codice come il nostro unico strumento. Dichiariamo tutte le variabili lì dentro e se dobbiamo inserire qualche specifica, la inseriamo direttamente al suo interno.

A volte però questa potrebbe non essere la strada giusta, per una serie di ragioni.

Le ragioni più importanti che mi vengono in mente sotto questo punto di vista sono principalmente due:

  • Dover andare ogni volta a metter mano al codice per poter cambiare qualche parametro
  • Non poter riutilizzare il codice per progetti simili ma diversi

Naturalmente, la struttura del file di configurazione dipende molto dal tipo di task che dobbiamo andare a svolgere.

Questi file possono essere semplicissimi, magari con una sola riga di codice (che equivale di solito ad una specifica), oppure possono avere strutture molto complesse, magari sequenziali o interconnesse.

Non esiste un estensione standard, né una struttura predefinita per un config file. Solitamente però uno dei formati più utilizzati è il JSON, che è facilmente leggibile da Python ed è molto semplice da manipolare.

2. COME USARE UN CONFIG FILE NEL CODICE

Ora che abbiamo capito cos’è un config file e a cosa serve, vediamo come possiamo usarlo nel nostro codice per renderlo più efficiente e smart.

Naturalmente il file config va opportunatamente scritto e poi importato nel nostro script Python, in modo da poterne usare le configurazioni al suo interno. Per far questo useremo il modulo json di Python.

Immaginiamo di avere una mailing list e di voler mandare ad alcuni dei nostri contatti un messaggio personalizzato.

scenario 1: inviamo lo stesso messaggio a tutti, cambiando solo il nome per salutare il nostro destinatario

Apriamo un qualunque editor di testo e iniziamo a scrivere il nostro json.

Config
Config

Salviamo il file con il nome config.json

Come si può ben vedere, in questo caso è semplicissimo, abbiamo solo inserito un campo chiamato mail_list in cui abbiamo messo le nostre email. Il nostro obiettivo sarà leggere da Python quelle mail e mandare ad ognuno un messaggio.

Potremmo usare una funzione di questo tipo per farlo:

def parse_config(config):
    ## leggo il file config e lo salvo in una variabile configuration
    with open(config, "r") as jsonfile:
        configuration = json.load(jsonfile)
    return configuration

Basterà fornire il path del config (magari un semplice “config.json”) e il nostro caro Python leggerà il file. Se stampassimo questo configuration avremmo il seguente risultato:

{'mail_list': ['davide.nardini@gmail.com',
  'diego_armando_maradona@dios.it',
  'tarantinoquentino@movies.com']}

Il type() di questo output è un dizionario, in cui la chiave è mail_list e come valore la lista di indirizzi. Con il comando list(configuration.values())[0] prendiamo la lista delle mail in modo da poterla usare per scrivere il messaggio.

A questo punto possiamo crearci una funzione che prenda in input la mail e che da essa scriva il messaggio, nel seguente modo:

def create_message(mail):
    ## prendo in input la mail e la inserisco nel testo
    message = f"""
    Caro {mail},
    Pulp Learning ti pensa sempre e
    con questa mail vuole mandarti un saluto!
    Vienici a trovare al link: https://pulplearning.altervista.org/
    Ti aspettiamo con torta e biscotti :D
    """
    return message

Anche qui molto semplice: sostituisce {mail} con un valore che gli passiamo e così compone il nostro messaggio.

Non ci resta che mettere tutto insieme (per semplicità faremo una funzione-contenitore send_mail) e guardare il risultato!

import json

def send_mail(config):
## genero una funzone che prende in input il config
## e stampa un messaggio per ogni mail presente nel config

def parse_config(config):
    ## leggo il file config e lo salvo in una variabile configuration
    with open(config, "r") as jsonfile:
        configuration = json.load(jsonfile)
    return configuration

def get_mail(configuration):
    ## estraggo dal config la lista delle mail
    list_mail = list(configuration.values())[0]
    return list_mail

def create_message(mail):
    ## prendo in input la mail e la inserisco nel testo
    message = f"""
    Caro {mail},
    Pulp Learning ti pensa sempre e
    con questa mail vuole mandarti un saluto!
    Vienici a trovare al link: https://pulplearning.altervista.org/
    Ti aspettiamo con torta e biscotti :D
    """
    return message

configuration = parse_config(config)
list_mail = get_mail(configuration)

for mail in list_mail:
    ## scrivo un messaggio per ogni mail
    message = create_message(mail)
    print(message)
    print("------")

Definita la mia funzione, non mi resta che chiamarla.

send_mail("config.json")

Et voilà, il nostro risultato:

        Caro davide.nardini@gmail.com,
        Pulp Learning ti pensa sempre e
        con questa mail vuole mandarti un saluto!
        Vienici a trovare al link: https://pulplearning.altervista.org/
        Ti aspettiamo con torta e biscotti :D
        
------

        Caro diego_armando_maradona@dios.it,
        Pulp Learning ti pensa sempre e
        con questa mail vuole mandarti un saluto!
        Vienici a trovare al link: https://pulplearning.altervista.org/
        Ti aspettiamo con torta e biscotti :D
        
------

        Caro tarantinoquentino@movies.com,
        Pulp Learning ti pensa sempre e
        con questa mail vuole mandarti un saluto!
        Vienici a trovare al link: https://pulplearning.altervista.org/
        Ti aspettiamo con torta e biscotti :D
        
------

Posso aggiungere quanti indirizzi voglio al config e la mia funzione farà il resto.

SCENARIO 2: CONFIGURIAMO IL NOSTRO FILE IN MODO DA PREVEDERE ALTRE IMPOSTAZIONI

Benissimo, però fin qui niente di particolarmente eccitante.

O meglio, molto utile perché il codice è immobile, quindi anche un non tecnico (uno che non conosce Python) potrà, cambiando il config, decidere a chi inviare la mail.

Però possiamo spingerci oltre, per esempio potendo scegliere senza dover ogni volta cancellare qualcuno se mandare o meno un messaggio.

{
"mail_list": [

   {"davide.nardini@gmail.com":0},
   {"diego_armando_maradona@dios.it":1},
   {"tarantinoquentino@movies.com":1}
]

}

Accanto ad ogni mail abbiamo aggiunto uno 0 o un 1. Gli 0 non riceveranno il messaggio, mentre gli 1 sì.

A questo punto cambiamo il codice per accettare questa ulteriore configurazione:

for mail in list_mail:
    for k,v in mail.items():
        if v == 1:
            message = create_message(k)
            print(message)
            print("------")
        else:
            pass

Poiché adesso "mail" non è più una lista ma un dizionario (composto da chiave: mail e valore: 0/1), ci basterà iterare questi valori e, qualora il valore “v” sia 1 scrivere il messaggio.

Se aggiungiamo quel pezzetto alla fine del nostro codice infatti il risultato sarà:

        Caro diego_armando_maradona@dios.it,
        Pulp Learning ti pensa sempre e
        con questa mail vuole mandarti un saluto!
        Vienici a trovare al link: https://pulplearning.altervista.org/
        Ti aspettiamo con torta e biscotti :D
        
------

        Caro tarantinoquentino@movies.com,
        Pulp Learning ti pensa sempre e
        con questa mail vuole mandarti un saluto!
        Vienici a trovare al link: https://pulplearning.altervista.org/
        Ti aspettiamo con torta e biscotti :D
        
------

Il povero davide.nardini@gmail.com non ha ricevuto la mail… E vabbè.

conclusioni

In questo tutorial abbiamo visto cos’è un file di configurazione e quando possiamo utilizzarlo.

Abbiamo visto poi come poterlo usare nel nostro codice Python scrivendo il file con il formato JSON.

Naturalmente, il caso illustrato è molto semplice e non presenta particolari complicazioni, ma il config permette di impostare qualunque cosa a qualsiasi grado di complessità.

E’ quindi molto molto utile quando abbiamo dei progetti che richiedono configurazioni dinamiche.

La cosa più utile è che possiamo settare ogni possibile configurazione senza dover metter mano al codice, una volta che è stato predisposto ad accettare il nostro file.