Variables de entorno de Python y cómo trabajar con ellas

¿Quieres gestionar mejor tu configuración? Aprenda a trabajar con variables de entorno en Python.

Cuando estaba aprendiendo Python por mi cuenta, creaba proyectos para aplicar lo que acababa de aprender. Un subconjunto de los que implicaban conectarse a una base de datos y consultarla utilizando Python. Lo que significaba que necesitaba almacenar la configuración de la base de datos y la información confidencial, como el nombre de usuario y la contraseña, para la autenticación.

Codificar información tan confidencial en un script de Python no era una buena idea. Y aprendí a usar archivos de configuración y variables de entorno, junto con los módulos integrados de Python para trabajar con ellos.

Entonces, cada vez que necesito usar información confidencial, como contraseñas y claves API en mis aplicaciones, las configuro como variables de entorno y las busco según sea necesario. En este tutorial, lo guiaré a través de las variables de entorno y cómo trabajar con ellas en Python.

¿Qué son las variables de entorno?

Las variables de entorno son variables externas a su aplicación que almacenan información de configuración, ajustes del sistema y similares. Por lo general, son administrados por el sistema operativo o el entorno de la aplicación. Las características clave de las variables de entorno incluyen:

  • Pares nombre-valor: las variables de entorno constan de un nombre (también conocido como clave) y un valor correspondiente.
  • Alcance del sistema: puede establecer variables de entorno a nivel del sistema, haciéndolas accesibles para todos los procesos que se ejecutan en el sistema. Si es necesario, también puede modificarlos o definirlos a nivel de aplicación, afectando solo a esa aplicación específica.
  • Dinámico y mutable: puede modificar las variables de entorno durante el tiempo de ejecución, lo que brinda flexibilidad.

Cómo son útiles las variables de entorno

Las variables de entorno ofrecen varios beneficios para administrar la configuración y la información confidencial en sus aplicaciones Python:

  • Separación de preocupaciones: al almacenar la configuración fuera de su código, mantiene las preocupaciones de la gestión de la configuración separadas de la lógica de su aplicación.
  • Seguridad: puede almacenar datos confidenciales, como claves API y credenciales de bases de datos, en variables de entorno, sin exponerlos en el código fuente, lo que reduce el riesgo de exposición.
  • Flexibilidad: con las variables de entorno, actualizar los ajustes de configuración es simple, ya que puede actualizar/realizar cambios fuera del código base. Las variables de entorno le permiten ajustar la configuración sin modificar su código. Esta flexibilidad es especialmente útil para implementar aplicaciones en diferentes entornos o al actualizar credenciales.

En las siguientes secciones de este tutorial, exploraremos cómo configurar, acceder y administrar variables de entorno en Python y cómo mejoran la administración de la configuración en sus proyectos.

Cómo configurar variables de entorno

Puede configurar variables de entorno utilizando la línea de comando. El alcance de dichas variables de entorno se aplica sólo a la sesión actual y no persisten fuera de la sesión actual.

Si está en una máquina Mac o Linux, puede configurar una variable de entorno en su sesión actual de terminal de esta manera:

export MY_VARIABLE=my_value

Si es usuario de Windows, puede configurar una variable de entorno temporalmente como se muestra:

set MY_VARIABLE=my_value

Acceder a variables de entorno en Python

Python proporciona la módulo del sistema operativo para la funcionalidad relacionada con el sistema operativo. Y os.environ es un diccionario de variables de entorno. Los nombres de las variables de entorno y sus valores son las claves y valores del diccionario, respectivamente.

De modo que puede acceder a los valores de las variables de entorno, utilizando (sus nombres como) las claves, tal como accedería a los elementos de un diccionario.

Aquí hay un par de ejemplos:

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

Hasta ahora, todo bien. Pero, ¿qué sucede si intentas acceder al valor de una variable de entorno que nunca se configuró?

Intentemos acceder a API_KEY que aún no hemos configurado:

print(os.environ['API_KEY'])

Como era de esperar, obtendrá un KeyError:

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

Manejo de errores clave

Puede manejar KeyError como se muestra:

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.')

Este enfoque no detiene abruptamente la ejecución del programa cuando se genera una excepción KeyError. Sin embargo, proporciona un mensaje de error descriptivo:

# Output
API_KEY is not set. Please configure it.

Entonces, cuando el resto del programa no se ejecuta como se esperaba, sabemos que no hemos configurado una variable de entorno requerida.

Accediendo a variables de entorno utilizando el método get()

Puede utilizar el método de diccionario get() para obtener el valor de una variable de entorno. En lugar de un KeyError, el método get() devuelve Ninguno si no se encuentra la variable.

Acceder a la variable NOT_SET que no hemos configurado devuelve Ninguno:

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

Prefiero generar un error clave cuando la variable de entorno no está configurada. Luego déjelo pasar en silencio o subsumirse en Ninguno que devuelve el método get().

Pero el método get() es útil cuando podemos pasar un valor predeterminado para una variable de entorno particular si no está configurada.

He aquí un ejemplo:

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

Cómo gestionar la configuración con variables de entorno

Ahora tomemos un par de ejemplos prácticos en los que usamos variables de entorno en nuestra aplicación.

Ejemplo 1: configuración de los parámetros de conexión de la base de datos

Supongamos que desea conectarse a una base de datos PostgreSQL desde Python. Para hacerlo, puedes instalar y usar el conector psycopg2:

pip install psycopg2

En este ejemplo, utilizamos variables de entorno para configurar los parámetros de conexión de la base de datos. Si las variables de entorno no están configuradas, proporcionamos valores predeterminados para usar.

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}')

Ejemplo 2: gestión de claves API

Tomemos otro ejemplo que implica el uso de claves API.

Además de la interfaz ChatGPT, también puede utilizar la API de OpenAI para admitir OpenAI LLM en sus aplicaciones.

Cuando se registra para obtener una cuenta OpenAI, (normalmente verá) algunos créditos API gratuitos por tiempo limitado. Obtenga su clave API navegando a Configuración> Ver claves API.

Puede utilizar el SDK de Open AI Python y un marco como LangChain para crear aplicaciones. Para hacerlo necesitas instalar las bibliotecas (en un entorno virtual) usando pip:

pip install openai
pip install langchain 

A continuación se explica cómo puede configurar OPENAI_API_KEY como variable de entorno:

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

Ahora puede acceder a los LLM de Open AI en su script de esta manera:

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

Cómo modificar variables de entorno en Python

Puede acceder al diccionario os.environ desde el módulo del sistema operativo para modificar las variables de entorno dentro del proceso actual de Python:

import os

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

En Python, puedes usar el módulo de subproceso para generar subprocesos a partir de un script Python existente. Lo cual resulta útil cuando desea ejecutar programas del sistema en Python.

En el siguiente ejemplo, modificamos la variable de entorno PATH accediendo al diccionario os.environ. Luego ejecutamos echo $PATH como subproceso:

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}')

Vemos que la RUTA toma el valor de /custom/path:

# Output
/custom/path

Alcance de las variables de entorno modificadas

Es importante tener en cuenta que estas actualizaciones de variables de entorno son temporales y solo son válidas para el proceso actual de Python. Una vez que finaliza el script, los cambios se descartan:

  • Proceso actual de Python: cuando modifica una variable de entorno usando os.environ dentro de su script de Python, el cambio es local para el proceso de Python actual. No afectará a otros procesos en ejecución ni a futuras sesiones de Python.
  • Procesos secundarios: los cambios en las variables de entorno realizados dentro del proceso actual de Python son heredados por los procesos secundarios creados por su secuencia de comandos. Por ejemplo, si genera un subproceso desde su secuencia de comandos Python (proceso principal), el proceso secundario tendrá acceso a las variables de entorno modificadas (como se ve en el ejemplo).
  • No en todo el sistema: las variables de entorno establecidas dentro de un script de Python no persistirán fuera de la ejecución de ese script.

Si necesita realizar cambios persistentes en las variables de entorno a nivel del sistema, normalmente deberá hacerlo utilizando métodos específicos del sistema operativo.

Cómo cargar archivos .env con python-dotenv

El biblioteca python-dotenv es un paquete de Python popular que simplifica el proceso de cargar variables de entorno desde un archivo .env en su proyecto de Python. Es particularmente útil cuando tiene múltiples entornos (por ejemplo, desarrollo, producción) con diferentes configuraciones y desea mantener estas configuraciones separadas de su código fuente.

Instalación de Python-dotenv

Para usar python-dotenv, primero debes instalarlo. Puedes instalarlo, dentro de un entorno virtual, usando pip, el administrador de paquetes de Python:

pip install python-dotenv

Cargando variables de entorno desde un archivo .env

Ahora puede crear un archivo .env en el directorio raíz de su proyecto y completarlo con pares clave-valor, al igual que las variables de entorno normales. Creemos el siguiente archivo .env con valores de marcador de posición:

API_KEY=your_api_key_here
DB_PASSWORD=your_database_password_here

Ahora puede cargar las variables de entorno desde el archivo .env usando python-dotenv así:

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}")

Observe que hemos usado os.getenv(VARIABLE_NAME) para obtener los valores de las variables de entorno. Esta también es una forma válida (y menos utilizada) de acceder a las variables de entorno.

Aquí está el resultado:

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

En este ejemplo:

  • Usamos load_dotenv() para cargar las variables de entorno definidas en el archivo .env en el entorno actual.
  • Luego usamos os.getenv() para acceder a las variables de entorno: API_KEY y DB_PASSWORD.

Conclusión

¡Y eso es una envoltura! Espero que haya aprendido cómo administrar la configuración y la información confidencial utilizando variables de entorno en aplicaciones Python. Hemos cubierto los conceptos básicos de configuración y acceso a variables de entorno, así como su uso práctico en la configuración de aplicaciones.

Si bien las variables de entorno son ciertamente útiles para separar la configuración del código fuente, debes almacenar las variables confidenciales como secretos en los casos de uso de producción. Para gestionar secretos, recomiendo explorar herramientas como Bóveda de HashiCorp o Administrador de secretos de AWS.