Las variables de entorno permiten separar configuración y secretos del código Python. Son apropiadas para claves de API, credenciales, URLs de bases de datos, modos de ejecución y opciones que cambian entre desarrollo, pruebas y producción. Evitan modificar el programa cada vez que cambia el entorno.
Leer una variable con os.getenv
Python expone las variables mediante os.environ y os.getenv:
import os
modo = os.getenv("APP_ENV", "development")
api_url = os.getenv("API_URL")
print(modo)
print(api_url)getenv devuelve None cuando la variable no existe, salvo que se indique un valor predeterminado. La documentación oficial de os.environ describe el acceso al entorno del proceso.
Variables obligatorias
Una configuración crítica no debería fallar silenciosamente:
import os
def obtener_variable(nombre: str) -> str:
valor = os.getenv(nombre)
if not valor:
raise RuntimeError(
f"Falta la variable obligatoria: {nombre}"
)
return valor
database_url = obtener_variable("DATABASE_URL")Usar una función central evita repetir validación. Revisa la guía de funciones en Python para organizar este tipo de utilidades.
Configurar variables en el sistema
En macOS o Linux puedes definir una variable temporal con export API_KEY="valor". En PowerShell se usa $env:API_KEY="valor". Estas variables existen para el proceso y los programas iniciados desde esa sesión. Para configuración permanente, utiliza las herramientas del sistema o del servicio de despliegue.
Archivos .env en desarrollo
Un archivo .env facilita el desarrollo local:
APP_ENV=development
DATABASE_URL=sqlite:///local.db
API_KEY=valor_localCon python-dotenv puedes cargarlo:
from dotenv import load_dotenv
import os
load_dotenv()
api_key = os.getenv("API_KEY")La página oficial de python-dotenv en PyPI explica su instalación y comportamiento. Añade .env a .gitignore para no publicarlo.
No guardar secretos en el repositorio
Una clave eliminada de un commit puede seguir presente en el historial. Si se publica accidentalmente, revócala y genera otra. No basta con borrar el archivo. También revisa logs, capturas y sistemas de integración continua.
Las variables de entorno reducen el riesgo, pero no son un almacén secreto perfecto. En producción puede ser mejor utilizar un gestor de secretos del proveedor de nube o de la plataforma.
Convertir tipos
Las variables se reciben como texto. Convierte y valida:
import os
debug = os.getenv("DEBUG", "false").lower() == "true"
puerto = int(os.getenv("PORT", "8000"))
timeout = float(os.getenv("TIMEOUT", "5.0"))Controla errores cuando el contenido pueda ser inválido. Un valor como PORT=abc provoca ValueError. Es mejor fallar al iniciar con un mensaje claro que descubrir el problema durante una solicitud.
Configuración por entorno
Desarrollo, pruebas y producción suelen utilizar servicios diferentes. Puedes definir APP_ENV y cargar opciones según su valor, pero evita crear demasiadas ramas dispersas. Centraliza la configuración en un módulo o clase.
En aplicaciones web, la configuración segura es esencial. La guía de Django muestra dónde se usan ajustes como SECRET_KEY y DEBUG; el artículo de FastAPI explica el mismo principio para APIs.
Type hints y configuración
Una función de configuración puede usar anotaciones para aclarar resultados. Los type hints en Python facilitan detectar conversiones olvidadas y ayudan a los editores. Para proyectos grandes, una dataclass o un modelo de configuración puede agrupar campos obligatorios y valores predeterminados.
Pruebas con variables de entorno
Las pruebas no deberían depender del entorno real del desarrollador. Configura valores temporales con herramientas de pytest o modifica os.environ durante la prueba, restaurándolo después. Nunca ejecutes pruebas automatizadas contra credenciales de producción.
Errores comunes
Los errores frecuentes incluyen asumir que la variable existe, olvidar convertir tipos, registrar secretos completos, compartir el archivo .env, reutilizar claves entre entornos y usar nombres poco claros. También es problemático cargar el archivo en producción sin comprender qué valores prevalecen.
Buenas prácticas
Documenta las variables requeridas en un archivo de ejemplo como .env.example, pero usa valores ficticios. Valida todo al iniciar, aplica nombres consistentes, limita permisos y rota credenciales. En contenedores y plataformas de nube, utiliza la configuración nativa para inyectarlas.
Cuando un programa parece fallar solo en un servidor, verifica primero la configuración. Después, si el problema es rendimiento, utiliza herramientas como cProfile en un entorno seguro y reproducible. Separar configuración del código mejora seguridad, despliegue y mantenimiento.
Precedencia de configuración
Un proyecto puede recibir valores desde argumentos, variables del sistema, archivos locales y valores predeterminados. Define una precedencia explícita. Por ejemplo: argumentos de línea de comandos, entorno real, archivo .env y finalmente valor predeterminado. Sin una regla, un desarrollador puede cambiar el archivo y no entender por qué el programa sigue utilizando otra configuración.
Nombres y prefijos
Usa nombres en mayúsculas y un prefijo de aplicación, como ACADEMIFY_DATABASE_URL, para evitar colisiones con otras herramientas. Separa conceptos: una variable booleana debería tener un nombre como APP_DEBUG, mientras que una URL debe indicar el servicio. Los nombres consistentes facilitan documentación y automatización.
Evitar fugas en logs
No imprimas el diccionario completo del entorno durante la depuración. Puede contener tokens, credenciales de nube y contraseñas. Registra únicamente si una variable está presente o muestra una versión parcialmente ocultada. También revisa mensajes de error de bibliotecas, porque algunas incluyen URLs de conexión con usuario y contraseña.






