lunes, 23 de marzo de 2026

Automatizacion con Python - Cap2 - parte 1

Capítulo 02 // Parte 1

Automatización de Tareas Simplificada

Python Automation Cookbook — Introducción y Preparar una Tarea

Para automatizar tareas de manera adecuada, necesitamos una forma de hacer que se ejecuten automáticamente en los momentos apropiados. Una tarea que necesita ser iniciada manualmente no está realmente completamente automatizada.

Sin embargo, para poder dejarlas ejecutándose en segundo plano mientras nos preocupamos por asuntos más urgentes, la tarea necesitará ser adecuada para ejecutarse en modo "disparar y olvidar". Deberíamos poder monitorear que se ejecuta correctamente, estar seguros de que capturamos información relevante, y saber si ha habido algún error durante su ejecución.

Asegurar que un software se ejecute consistentemente con alta confiabilidad es en realidad un asunto muy importante. Es un área que requiere conocimiento especializado y personal, quienes típicamente reciben nombres como sysadmin, operaciones o SRE (Site Reliability Engineering).

CONTENIDO_CAP02

En Este Capítulo

  • Preparar una tarea — Diseñar tareas para ejecución autónoma
  • Configurar un trabajo cron — Programar tareas periódicas en Unix/Linux
  • Capturar errores y problemas — Logging y manejo de excepciones
  • Enviar notificaciones por email — Alertas automáticas vía SMTP
RECETA_01

Preparar una Tarea

Todo comienza con definir precisamente el trabajo que necesita ejecutarse, y diseñarlo de manera que no requiera intervención humana para ejecutarse.

Características Ideales

  • Punto de entrada único y claro: Sin confusión sobre cómo iniciar la tarea
  • Parámetros claros: Si hay parámetros, deben ser lo más explícitos posible
  • Sin interactividad: Detener la ejecución para solicitar información del usuario no es posible
  • El resultado debe almacenarse: Para poder verificarlo en un momento diferente al de su ejecución
  • Resultado claro: Para una tarea automatizada, el resultado final debe ser lo más conciso y directo posible
  • Los errores deben registrarse: Para analizar qué salió mal
Para evitar la interactividad, no uses ninguna función que espere entrada del usuario, como input. ¡Recuerda eliminar los puntos de interrupción del depurador!

Paso 1: Script Básico

prepare_task_step1.py
import argparse

def main(number, other_number):
    result = number * other_number
    print(f'The result is {result}')

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('-n1', type=int, help='A number', default=1)
    parser.add_argument('-n2', type=int, help='Another number', default=1)
    
    args = parser.parse_args()
    main(args.n1, args.n2)
$ python3 prepare_task_step1.py -n1 3 -n2 7
The result is 21

Paso 2: Agregar Archivo de Configuración

prepare_task_step3.py
import argparse
import configparser

def main(number, other_number):
    result = number * other_number
    print(f'The result is {result}')

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('-n1', type=int, help='A number', default=1)
    parser.add_argument('-n2', type=int, help='Another number', default=1)
    parser.add_argument('--config', '-c', type=argparse.FileType('r'),
                        help='config file')
    
    args = parser.parse_args()
    
    if args.config:
        config = configparser.ConfigParser()
        config.read_file(args.config)
        # Transformando valores a enteros
        args.n1 = int(config['ARGUMENTS']['n1'])
        args.n2 = int(config['ARGUMENTS']['n2'])
    
    main(args.n1, args.n2)
config.ini
[ARGUMENTS]
n1=5
n2=7
$ python3 prepare_task_step3.py -c config.ini
The result is 35

Paso 3: Salida a Archivo

prepare_task_step6.py
import argparse
import sys
import configparser

def main(number, other_number, output):
    result = number * other_number
    print(f'The result is {result}', file=output)

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('-n1', type=int, help='A number', default=1)
    parser.add_argument('-n2', type=int, help='Another number', default=1)
    parser.add_argument('--config', '-c', type=argparse.FileType('r'),
                        help='config file')
    parser.add_argument('-o', dest='output', type=argparse.FileType('w'),
                        help='output file',
                        default=sys.stdout)
    
    args = parser.parse_args()
    
    if args.config:
        config = configparser.ConfigParser()
        config.read_file(args.config)
        args.n1 = int(config['ARGUMENTS']['n1'])
        args.n2 = int(config['ARGUMENTS']['n2'])
    
    main(args.n1, args.n2, args.output)
$ python3 prepare_task_step6.py -c config.ini -o result.txt
$ cat result.txt
The result is 35
El módulo argparse permite definir archivos como parámetros con el tipo argparse.FileType, y los abre automáticamente. El módulo configparser permite leer archivos de configuración en formato INI.
ANÁLISIS

Cómo Funciona

El módulo argparse nos permite definir archivos como parámetros, con el tipo argparse.FileType, y los abre automáticamente. Esto es muy práctico y generará un error si la ruta del archivo lleva a una ubicación inválida.

Recuerda abrir el archivo en el modo correcto. La r lo abre para lectura, mientras que w lo abre para escritura. De manera predeterminada, los archivos están disponibles solo para lectura.

El módulo configparser permite leer archivos de configuración en el formato INI. Este formato permite agrupar valores bajo encabezados (como [ARGUMENTS]), así como comentarios usando las líneas # o ;.

Como regla general, intenta evitar crear demasiados parámetros de entrada y configuración si la tarea tiene un objetivo muy específico. Un parámetro que nunca cambia probablemente está bien definido como una constante. ¡Intenta encontrar tu propio equilibrio adecuado!

Basado en "Python Automation Cookbook" // Jaime Buelta

Traducción al español — Capítulo 2, Parte 1 de 4