Saltar a contenido

Precauciones previas y tips

Antes de intentar el despliegue de aplicaciones Python en contenedores es conveniente verificar algunos pasos previos, con el fin de minimizar errores posteriores.

Agrupar importaciones

Si en el proyecto hay archivos o directorios de módulos, configuraciones, traducciones, etc. es conveniente que estos archivos estén agrupados en subdirectorios de la carpeta del proyecto, con el fin de ser copiados fácilmente adentro del contenedor en las rutas correctas.

Comandos ejecutables

Hay que atención al comando utilizado para la ejecución de la rutina y también a sus argumentos posicionales y opciones de entrada. De esta manera el comando podrá ser adaptado al archivo Dockerfile.

En este sentido, tener en cuenta que el alias py para el intérprete de Python normalmente no está disponible en el contenedor.

Versiones de dependencias

Si el programa requiere paquetes adicionales entonces es importante fijar las versiones usadas indicando sus etiquetas de versión. Esto prevendrá que el código se "rompa" si los paquetes usados son actualizados descontroladamente.

Por ejemplo, si se usa PIP para gestionar los paquetes el comando pip freeze sirve asegurar las versiones de todos los paquetes en archivo TXT.

En el caso de Poetry, ese mismo control fino se puede conseguir con el archivo LOCK. Otra opción es el uso del archivo TOML que define el versionado de una manera normalmente más laxa.

Versiones de Python

No todas las versiones de Python son capaces de correr las rutinas debidos a los cambios de sintaxis, prestaciones nuevas y prestaciones obsoletas, etc. Por este motivo debe elegirse como base una imagen de Python cuya versión instalada del intérprete pueda ejecutar el código fuente correctamente.

Compatibilidad con la imagen

Las dependencias usadas deben ser capaces de ser usadas en el sistema operativo de la imagen.

Por ejemplo: el paquete psycopg2, que es necesario para interactuar con bases de datos PostgreSQL, sólo funciona el Windows. Su equivalente para sistemas GNU/Linux es el paquete psycopg2-binary y es ésta la versión que funcionará en las imágenes de Python más habituales.

En los contenedores la salida de texto por consola a menudo no está implementada, por este motivo escribir texto mediante la función print() es problemático. La alternativa es la lectura de texto desde la ventana de logs, la cual es de uso estándar en los contenedores. Para ello es necesario el uso de las funciones de logging, las cuales requieren importación y configuración para su uso:

Logging - configuracion previa
import logging

# uso de la consola de logs
logging.basicConfig(
    level=logging.INFO, # mínimo nivel de log a publicar
    format="%(asctime)s - %(levelname)s - %(message)s", #info incorporada
    )

Los logs se pueden guardar en archivo al tiempo que se muestran en consola. La configuración se realiza fácilmente con ayuda de las funciones StreamHandler() yFileHandler() del módulo logging tal como se muestra a continuación:

logging en archivo
import logging

logging.basicConfig(
    level=logging.INFO, # mínimo nivel de log a publicar
    format="%(asctime)s - %(levelname)s - %(message)s", #info incorporada
    handlers=[
        # salida por consola
        logging.StreamHandler(), 
        # salida por archivo
        logging.FileHandler(
            filename=ruta_archivo,
            mode="a",             # agregado ('append')
            encoding="utf-8",
            delay=True,
            ),
        ],
    )

Hay varias funciones para crear los mensajes de log, las cuales tienen distintos niveles de jerarquía:

Logging - funciones de salida
logging.debug("Texto de DEBUG")         # mínima jerarquía
logging.info("Texto de INFO")
logging.warning("Texto de WARNING")
logging.error("Texto de ERROR")
logging.critical("Texto de CRITICAL")   # máxima jerarquía

Las llamadas a funciones de logging que no cumplan la jerarquía mínima configuradas serán ignoradas durante la ejecución.

f-strings vs lazy format

Es prudente evitar los f-strings, porque si el tipo de datos de entrada del string es erróneo se puede producir una excepción que encubrirá la información del reporte original.

Su reemplazo son los strings con lazy format.

Por ejemplo, la línea:

formatted-string - entero, 4 espacios
logging.info(f"valor: {entero:4}")

se convierte en:

lazy format - entero, 4 espacios
logging.info("valor: %4i", entero)

Más información sobre el logging: módulo logging