Variabili d’ambiente Python e come lavorare con esse

Vuoi gestire meglio la tua configurazione? Scopri come lavorare con le variabili di ambiente in Python.

Quando insegnavo Python da solo, creavo progetti per applicare ciò che avevo appena imparato. Un sottoinsieme di quelli coinvolti nella connessione a un database e nell’interrogarlo utilizzando Python. Ciò significava che dovevo archiviare la configurazione del database e informazioni sensibili come nome utente e password per l’autenticazione.

L’hardcoding di informazioni così sensibili in uno script Python non è stata una buona idea. E ho imparato come utilizzare i file di configurazione e le variabili di ambiente, insieme ai moduli integrati di Python per lavorare con essi.

Pertanto, ogni volta che devo utilizzare informazioni sensibili come password e chiavi API nelle mie applicazioni, le imposto come variabili di ambiente e le recupero secondo necessità. In questo tutorial ti guiderò attraverso le variabili di ambiente e come lavorare con esse in Python.

Cosa sono le variabili d’ambiente?

Le variabili di ambiente sono variabili esterne all’applicazione che memorizzano informazioni di configurazione, impostazioni di sistema e simili. In genere sono gestiti dal sistema operativo o dall’ambiente applicativo. Le caratteristiche chiave delle variabili di ambiente includono:

  • Coppie nome-valore: le variabili di ambiente sono costituite da un nome (noto anche come chiave) e un valore corrispondente.
  • Ambito del sistema: è possibile impostare variabili di ambiente a livello di sistema, rendendole accessibili a tutti i processi in esecuzione sul sistema. Se necessario, puoi anche modificarli o definirli a livello di applicazione, influenzando solo quella specifica applicazione.
  • Dinamico e mutabile: è possibile modificare le variabili di ambiente durante il runtime, garantendo flessibilità.

In che modo le variabili d’ambiente sono utili

Le variabili d’ambiente offrono diversi vantaggi per la gestione della configurazione e delle informazioni sensibili nelle applicazioni Python:

  • Separazione degli aspetti: archiviando la configurazione al di fuori del codice, mantieni gli aspetti della gestione della configurazione separati dalla logica dell’applicazione.
  • Sicurezza: puoi archiviare dati sensibili, come chiavi API e credenziali del database, in variabili di ambiente, senza esporli nel codice sorgente, riducendo il rischio di esposizione.
  • Flessibilità: con le variabili di ambiente, l’aggiornamento delle impostazioni di configurazione è semplice, poiché è possibile aggiornare/apportare modifiche al di fuori della codebase. Le variabili di ambiente ti consentono di regolare le impostazioni di configurazione senza modificare il codice. Questa flessibilità è particolarmente utile per la distribuzione di applicazioni in ambienti diversi o durante l’aggiornamento delle credenziali.

Nelle sezioni seguenti di questo tutorial, esploreremo come impostare, accedere e gestire le variabili di ambiente in Python e come migliorano la gestione della configurazione nei tuoi progetti.

Come impostare le variabili d’ambiente

È possibile impostare le variabili di ambiente utilizzando la riga di comando. L’ambito di tali variabili di ambiente si applica solo alla sessione corrente e non persistono al di fuori della sessione corrente.

Se utilizzi un computer Mac o Linux, puoi impostare una variabile di ambiente nella sessione terminale corrente in questo modo:

export MY_VARIABLE=my_value

Se sei un utente Windows, puoi impostare temporaneamente una variabile di ambiente come mostrato:

set MY_VARIABLE=my_value

Accedi alle variabili d’ambiente in Python

Python fornisce il modulo del sistema operativo per funzionalità relative al sistema operativo. E os.environ è un dizionario di variabili d’ambiente. I nomi delle variabili d’ambiente e i loro valori sono rispettivamente le chiavi e i valori del dizionario.

Quindi puoi accedere ai valori delle variabili di ambiente, utilizzando (i loro nomi come) le chiavi, proprio come accederesti agli elementi di un dizionario.

Qui ci sono un paio di esempi:

import os
print(os.environ['HOME'])
# Output: /home/balapriya
print(os.environ['USER'])
# Output: balapriya

Fin qui tutto bene. Ma cosa succede se provi ad accedere al valore di una variabile d’ambiente che non è mai stata impostata?

Proviamo ad accedere ad API_KEY che non abbiamo ancora impostato:

print(os.environ['API_KEY'])

Come previsto, riceverai un KeyError:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<frozen os>", line 679, in __getitem__
KeyError: 'API_KEY'

Gestione degli errori chiave

Puoi gestire KeyError come mostrato:

import os

try:
	api_key = os.environ['API_KEY']
	print(f'API_KEY is set to: {api_key}')
except KeyError:
	print('API_KEY is not set. Please configure it.')

Questo approccio non interrompe bruscamente l’esecuzione del programma quando viene sollevata un’eccezione KeyError. Tuttavia, fornisce un messaggio di errore descrittivo:

# Output
API_KEY is not set. Please configure it.

Quindi, quando il resto del programma non viene eseguito come previsto, sappiamo di aver mancato l’impostazione di una variabile d’ambiente richiesta.

Accesso alle variabili d’ambiente utilizzando il metodo get()

È possibile utilizzare il metodo del dizionario get() per ottenere il valore di una variabile d’ambiente. Invece di un KeyError, il metodo get() restituisce None se la variabile non viene trovata.

L’accesso alla variabile NOT_SET che non abbiamo impostato restituisce None:

print(os.environ.get('NOT_SET'))
# Output: None

Preferisco generare un errore chiave quando la variabile di ambiente non è impostata. Quindi lascia che passi silenziosamente o venga incluso nel None restituito dal metodo get().

Ma il metodo get() è utile quando possiamo passare un valore predefinito per una particolare variabile d’ambiente se non è impostata.

Ecco un esempio:

print(os.environ.get('HOME','/home/user'))
# Output: /home/balapriya

Come gestire la configurazione con variabili d’ambiente

Ora facciamo un paio di esempi pratici in cui utilizziamo le variabili d’ambiente nella nostra applicazione.

Esempio 1: configurazione dei parametri di connessione al database

Supponiamo che tu voglia connetterti a un database PostgreSQL da Python. Per fare ciò, puoi installare e utilizzare il connettore psycopg2:

pip install psycopg2

In questo esempio, utilizziamo le variabili di ambiente per configurare i parametri di connessione al database. Se le variabili di ambiente non sono impostate, forniamo valori predefiniti da utilizzare.

import os
import psycopg2  

# Retrieve database configuration from environment variables
db_host = os.environ.get('DB_HOST', 'localhost')
db_port = os.environ.get('DB_PORT', '5432')
db_user = os.environ.get('DB_USER', 'myuser')
db_password = os.environ.get('DB_PASSWORD', 'mypassword')

# Establish a database connection
try:
	connection = psycopg2.connect(
    	host=db_host,
    	port=db_port,
    	user=db_user,
    	password=db_password,
    	database="mydb"
	)
	print('Connected to the database!')
except Exception as e:
	print(f'Error connecting to the database: {e}')

Esempio 2: gestione delle chiavi API

Prendiamo un altro esempio che prevede l’uso delle chiavi API.

Oltre all’interfaccia ChatGPT, puoi anche utilizzare l’API OpenAI per supportare OpenAI LLM nelle tue applicazioni.

Quando ti registri per un account OpenAI, vedresti (in genere) alcuni crediti API gratuiti a tempo limitato. Ottieni la tua chiave API accedendo a Impostazioni > Visualizza chiavi API.

Puoi utilizzare Open AI Python SDK e un framework come LangChain per creare applicazioni. Per fare ciò è necessario installare le librerie (in un ambiente virtuale) utilizzando pip:

pip install openai
pip install langchain 

Ecco come puoi impostare OPENAI_API_KEY come variabile di ambiente:

import os
os.environ["OPENAI_API_KEY"]='your-api-key'

Ora puoi accedere a Open AI LLM nel tuo script in questo modo:

from langchain.llms import OpenAI
model=OpenAI(model_name="gpt-3.5-turbo")

Come modificare le variabili d’ambiente in Python

Puoi accedere al dizionario os.environ dal modulo os per modificare le variabili di ambiente all’interno dell’attuale processo Python:

import os

# Modify an existing environment variable or create a new one
os.environ['MY_VARIABLE'] = 'new_value'

In Python, puoi usare il modulo del sottoprocesso per generare sottoprocessi dallo script Python esistente. Il che è utile quando vuoi eseguire programmi di sistema in Python.

Nell’esempio seguente, modifichiamo la variabile d’ambiente PATH accedendo al dizionario os.environ. Quindi eseguiamo echo $PATH come sottoprocesso:

import os
import subprocess

# Set a custom environment variable for the subprocess
os.environ['PATH'] = '/custom/path'

# Run a subprocess that accesses the PATH environment variable
result = subprocess.run("echo $PATH", shell=True, stdout=subprocess.PIPE)
output = result.stdout.decode()
print(output)
print(f'Subprocess output: {output}')

Vediamo che il PATH assume il valore di /custom/path:

# Output
/custom/path

Ambito delle variabili d’ambiente modificate

È importante notare che questi aggiornamenti delle variabili di ambiente sono temporanei e validi solo per il processo Python corrente. Una volta terminato lo script, le modifiche vengono annullate:

  • Processo Python corrente: quando modifichi una variabile di ambiente utilizzando os.environ all’interno del tuo script Python, la modifica è locale al processo Python corrente. Non influenzerà altri processi in esecuzione o future sessioni Python.
  • Processi secondari: le modifiche alle variabili di ambiente apportate all’interno del processo Python corrente vengono ereditate dai processi secondari creati dal tuo script. Ad esempio, se generi un sottoprocesso dal tuo script Python (processo genitore), il processo figlio avrà accesso alle variabili di ambiente modificate (come visto nell’esempio).
  • Non a livello di sistema: le variabili di ambiente impostate all’interno di uno script Python non persisteranno al di fuori dell’esecuzione di tale script.

Se è necessario apportare modifiche persistenti alle variabili di ambiente a livello di sistema, in genere è necessario farlo utilizzando metodi specifici del sistema operativo.

Come caricare file .env con python-dotenv

IL libreria python-dotenv è un popolare pacchetto Python che semplifica il processo di caricamento delle variabili di ambiente da un file .env nel tuo progetto Python. È particolarmente utile quando si hanno più ambienti (ad esempio, sviluppo, produzione) con configurazioni diverse e si desidera mantenere queste impostazioni separate dal codice sorgente.

Installazione di python-dotenv

Per utilizzare python-dotenv, devi prima installarlo. Puoi installarlo, all’interno di un ambiente virtuale, utilizzando pip, il gestore di pacchetti Python:

pip install python-dotenv

Caricamento di variabili d’ambiente da un file .env

Ora puoi creare un file .env nella directory root del tuo progetto e popolarlo con coppie chiave-valore, proprio come le normali variabili di ambiente. Creiamo il seguente file .env con valori segnaposto:

API_KEY=your_api_key_here
DB_PASSWORD=your_database_password_here

Ora puoi caricare le variabili di ambiente dal file .env usando python-dotenv in questo modo:

import os
from dotenv import load_dotenv

# Load environment variables from .env file
load_dotenv()

# Access the environment variables
api_key = os.getenv("API_KEY")
database_password = os.getenv("DB_PASSWORD")

# Print out the env variables
print(f"API Key: {api_key}")
print(f"Database Password: {database_password}")

Nota che abbiamo usato os.getenv(VARIABLE_NAME) per ottenere i valori delle variabili d’ambiente. Questo è anche un modo valido (e meno comunemente usato) per accedere alle variabili di ambiente.

Ecco l’output:

API Key: your-api-key-here
Database Password: your-database-url-here

In questo esempio:

  • Usiamo load_dotenv() per caricare le variabili di ambiente definite nel file .env nell’ambiente corrente.
  • Utilizziamo quindi os.getenv() per accedere alle variabili di ambiente: API_KEY e DB_PASSWORD.

Conclusione

E questo è tutto! Spero che tu abbia imparato come gestire la configurazione e le informazioni sensibili utilizzando le variabili di ambiente nelle applicazioni Python. Abbiamo trattato le nozioni di base sull’impostazione e l’accesso alle variabili di ambiente, nonché il loro utilizzo pratico nella configurazione delle applicazioni.

Sebbene le variabili di ambiente siano certamente utili per separare la configurazione dal codice sorgente, è necessario archiviare le variabili sensibili come segreti nei casi d’uso di produzione. Per la gestione dei segreti, consiglio di esplorare strumenti come HashiCorp Vault O Gestore dei segreti AWS.