¡Acceso ilimitado 24/7 a todos nuestros libros y vídeos! Descubra la Biblioteca Online ENI. Pulse aquí
¡Acceso ilimitado 24/7 a todos nuestros libros y vídeos! Descubra la Biblioteca Online ENI. Pulse aquí
  1. Libros
  2. Scripting Python en Linux
  3. Librería estándar y algunas otras
Extrait - Scripting Python en Linux Desarrolle sus herramientas de sistema
Extractos del libro
Scripting Python en Linux Desarrolle sus herramientas de sistema Volver a la página de compra del libro

Librería estándar y algunas otras

Introducción

Los capítulos anteriores le han permitido descubrir las bases procedimentales y los objetos del lenguaje Python.

A partir de estas bases, la comunidad alrededor de Python ha codificado, en el momento de escribir este libro, 218.066 proyectos o módulos.

Entonces, si alguna vez tiene la idea de escribir un gran módulo, primero haga una búsqueda en https://pypi.org (Python Package index).

A menudo, en los medios en los que hablamos del lenguaje Python, escuchamos las palabras ’librería estándar’ o ’stdlib’.

¿Qué es exactamente?

La librería estándar está formada por módulos incorporados con el código fuente de Python.

Ventaja evidente: si Python está instalado, también lo está el módulo de librería estándar.

Problema: en aras de la compatibilidad, los desarrolladores se ven obligados a mantener el código antiguo, incluso muy antiguo.

Además, incluso Guido Van Rossum lo dice: "A package in the stdlib has one foot in the grave" (un paquete en la stdlib tiene un pie en la tumba).

Por ejemplo, para la gestión de las opciones de la línea de comandos, existen:

  • getopt que todavía existe

  • optparse obsoleto (deprecated) en favor de argparse

  • argparse reemplazando optparse

y mientras buscamos, nos encontramos con el módulo docopt, que parece bastante práctico....

El comando pip

pip es el comando para instalar paquetes de Python integrados en las fuentes desde la versión 3.4.

Este comando automatiza la conexión al sitio https://pypi.org/, la descarga, la instalación e incluso la compilación del módulo solicitado.

Además, se ocupa de las dependencias de cada paquete.

La sintaxis, como siempre, es bastante simple:

pip <comando> <nombre_del_paquete> 

A continuación se muestran los comandos básicos:

pip install

para instalar un paquete

pip search

para buscar un paquete

pip show

para obtener información sobre los paquetes instalados

pip uninstall

para desinstalar

Detrás de este comando de tres letras, se encuentra el acceso a más de 200.000 módulos de Python.

Posteriormente, si es necesario descargar un módulo, se indicará cual.

Pip es una herramienta evolucionada y flexible, y aquí está el método para volver a instalar y/o sincronizar librerías de un entorno virtual a otro.

Para obtener una copia de un entorno de Python, es suficiente con aplicar el siguiente comando desde el entorno de origen:

pip freeze > requirements.txt 

Y en el entorno de destino:

pip install -r requirements.txt 

para obtener una instalación de las librerías.

RESUMEN

pip es un comando para buscar e instalar módulos de Python desde el directorio pypi.org.

’pip freeze requirements.txt’ y ’pip install...

Los módulos sys y os

Dos módulos se distinguen del resto: sys y os.

Estos son los módulos más cercanos al sistema y en aras de la compatibilidad, todavía hay algunas funcionalidades de bajo nivel. Pero en general, en estos casos es mejor buscar en el resto de la librería estándar o en módulos específicos.

1. El módulo sys

El módulo sys contiene parámetros mantenidos por el intérprete y funciones fuertemente relacionadas con el intérprete.

Estas son algunas de las variables más importantes:

sys.argv

Los argumentos de la línea de comandos; para una gestión de estos, consulte el módulo argparse.

sys.exit

Le permite salir del script correctamente especificando el código de retorno del shell.

sys.path

Las rutas de búsqueda de los módulos.

sys.platform

El tipo de plataforma en la que se ejecutará el script; esto le permite importar módulos específicos por plataforma.

sys.ps1 y sys.ps2

Los prompts del intérprete predeterminado ’>>>’ y ’…’.

sys.stdin

sys.stdout

sys.stderr

Los tres descriptores de archivos básicos utilizados por las funciones input() y print().

2. El módulo os

El módulo os le permite escribir scripts compatibles, independientemente del sistema operativo.

De esta manera, cambiar el directorio de trabajo o recorrer el directorio siempre...

Las opciones de la línea de comandos

Como hablamos al comienzo de este capítulo, Python viene con módulos para manejar la línea de comandos.

Existe:

  • getopt que todavía existe, un desertor del lenguaje C.

  • optparse también existe todavía, pero marcado como obsoleto.

  • argparse recomendado por los desarrolladores de la librería estándar.

Y hay otros, pero argparse, que en sí mismo es recomendable, no necesita dependencias ni llamadas a pip.

Se usa de esta manera:

  • Creación de un ’parser’, un objeto dedicado para analizar los argumentos

  • Adición del argumento ’archivo’ con una opción corta y larga y ayuda

  • Adición del argumento Modo verboso

  • Lanzamiento del análisis de los argumentos y almacenamiento del resultado en una variable ’opciones’, que se puede transmitir.

Aquí hay un ejemplo de script:

# archivo: argparse_1.py  
  
import argparse  
  
def mi_programa(opciones):  
   print("Mi programa ")  
   print("Opciones: %s " % opciones )  
  
if __name__ == '__main__':  
   ## gestión de los argumentos  
   parser = argparse.ArgumentParser()  
   parser.add_argument('-f', '--archivo', help='Nombre de archivo' ) ...

La interceptación de señales

La gestión de señales no es mucho más complicada que el resto, porque todo está en el módulo signal.

La primera señal que generalmente queremos administrar es la interrupción SIGINT.

Es suficiente con:

  1. importar el módulo signal

  2. crear una función que interceptará la señal que se desea

  3. asociar la señal a la función

Ejemplo de script

#archivo: signal_1.py  
  
import signal  
import sys  
  
def interrupcion(signal, contexto):  
   print("Cierre como consecuencia de CTRL-C")  
   sys.exit(0)  
  
signal.signal(signal.SIGINT, interrupcion)  
  
print("Inicio del bucle infinito...")  
while True:  
   pass 

La función debe aceptar dos argumentos: la señal en cuestión en forma de número entero y el contexto de ejecución durante la interceptación de la señal.

Ejemplo de ejecución

$ python signal_1.py  
Inicio del bucle infinito...  
^CCierre como consecuencia de CTRL-C 

Debe iniciar el script y luego usar la secuencia CTRL-C (tecla [Ctrl] + tecla ’C’) para detener el script.

Otro ejemplo práctico del uso de señales: las alarmas.

Aquí hay un script que muestra...

Los archivos temporales

Generar archivos temporales no tiene por qué ser una tarea tediosa.

Con demasiada frecuencia, el directorio /tmp se convierte en una papelera difícil de limpiar.

Python ofrece un módulo dedicado a los archivos temporales. Estamos hablando de él ahora porque este módulo se usará a menudo en nuestros ejemplos.

Gracias a la instrucción with, el módulo para la gestión de archivos temporales se ha convertido en un verdadero placer.

De hecho, con esta instrucción, el archivo temporal se elimina automáticamente y funciona incluso con los directorios.

Observe la simplicidad del código:

#archivo: temp1.py  
  
import tempfile  
  
data = [ 'línea 1\n', 'línea 2\n', 'línea 3\n' ]  
  
with tempfile.TemporaryFile(mode='w+') as fic:  
   fic.writelines( data )                     # escritura  
   fic.flush()                                # forzada  
   fic.seek(0)                                #...

Los módulos para las operaciones en los archivos y directorios

Se proporciona un cierto número de módulos para la gestión de directorios y archivos.

Muchos módulos y funciones provienen de su equivalente "línea de comando" y el objetivo no es reemplazar el shell por el lenguaje Python, sino usar las fortalezas de uno para completar las del otro.

1. os.path

Este es el módulo más antiguo y muchos de los scripts existentes se basan en este módulo.

Construir una ruta

os.path() 
p = os.path('/proc') 

Ruta absoluta

os.path.abspath('.')  # devuelve /home/chris 

Cambiar de directorio

os.chdir(p) 

Crear un directorio

os.mkdir( '/tmp/test') 

Listar los archivos

os.listdir(p)     #devuelve una lista 

pero hay mejores, mucho mejores

Existencia de un archivo

os.path.exists(p)    # devuelve True or False 

Otras funciones sobre las rutas os.path:

basename

Devuelve el último elemento de la ruta

>>> os.path.basename('/tmp/test')  
'test'  
# Atención si la ruta termina con '/'  
>>> os.path.basename('/tmp/test/')   
'' 

La función basename del shell devuelve ’test’.

dirname

Devuelve el nombre del directorio.

Existencia y pruebas de los archivos:

os.path.exists(ruta)

Devuelve True o false.

os.path.getsize(ruta)

Devuelve el tamaño en bytes.

os.path.isabs(ruta)

True si es una ruta absoluta.

os.path.isdir(ruta)

True si es un directorio.

os.path.isfile(ruta)

True si es un archivo.

os.path.islink(ruta)

True si es un enlace.

os.path.ismount(ruta)

True si es un punto de montaje.

os.path.samefile(c1, c2)

True si las dos rutas apuntan al mismo archivo o directorio.

os.path.sameopenfile (df1,df2)

True si ambos descriptores de archivo apuntan al mismo archivo o directorio.

Cálculo de ruta a partir de variables, abreviaturas u otros:

os.path.expandusers(ruta)

Reemplaza ~ o ~ usuario con el directorio real.

os.path.expandvars(ruta)

Reemplaza las variables con su valor y crea una ruta.

os.path.split(ruta)

Divide la ruta en una lista.

os.path.join(ruta,ruta...)

Recompone una ruta.

2. shutil

El módulo shutil le permite ejecutar comandos en archivos y directorios. Por supuesto, a veces hay mejores opciones en la línea de comandos, pero puede ser útil saber que existe.

Estas son algunas de estas funciones:

shutil.copy(origen...

La gestión de los procesos y subprocesos

El módulo subprocess le permite iniciar procesos, ejecutar comandos del sistema e incluso comunicarse con ellos.

En primer lugar, la ejecución de un comando simple:

>>> import subprocess  
>>> subprocess.run(["espeak", "hola"])  
CompletedProcess(args=['espeak', 'hola'], returncode=0) 

Normalmente, debería escuchar a su ordenador hablar con acento inglés.

1. Subprocess.run()

Con subprocess.run(), podemos dominar muchas cosas.

De hecho, todo lo que nos interesa...

Subprocess.run() se utiliza para ejecutar un comando del sistema, esperar a que se complete el comando y recuperar un objeto CompletedProcess que contiene el resultado y el estado del comando terminado.

Aquí hay un pequeño ejemplo:

#archivo: subprocess/sub1.py  
  
import subprocess  
  
comando = [ "ls", "-l" ]  
  
cmd = subprocess.run(comando, universal_newlines=True,  
stdout=subprocess.PIPE, stderr=subprocess.PIPE)  
  
print("=" * 30 )  
print("Comando: %s " % comando )  
print("=" * 30 )  
print(" return code: %s " % cmd.returncode)  
print("=" * 30 )  
print(" STDOUT: ")  
print(" %s " % cmd.stdout )  
print("=" * 30 )  
print(" STDERR: ")  
print(" %s " % cmd.stderr )  
print("=" * 30 ) 

En la ejecución, debería dar:

 $ python sub1.py  
==============================  
Comando: ['ls', '-l']  
==============================  
return code: 0  
==============================  
STDOUT:  
total 16  
-rw-rw-r-- 1 chris chris  162 nov.   2 12:40 bdd1.txt  
-rw-rw-r-- 1 chris chris    0 nov.   2 09:57 arc1  
-rw-rw-r-- 1 chris chris    0 nov.   2 09:57 arc2  
-rw-rw-r-- 1 chris chris    0 nov.   2 09:57 arc3  
-rw-rw-r-- 1 chris chris  413 nov.   2 10:01 sub1.py  
-rw-rw-r-- 1 chris chris 1246 nov.   2 17:08 sub2.py  
-rw-rw-r-- 1 chris chris  997 nov.   2 17:13 sub3.py  ...

Mathplotlib

Mathplotlib es una librería científica para generar gráficos.

Este tiene tanto éxito que unas pocas líneas de código permiten generar un gráfico simple.

Y todos saben que una imagen vale más que mil palabras.

Incluso podemos decir que un poco de código vale más que un párrafo largo.

A continuación, se muestra:

# archivo: mathplotlib1.py  
  
import matplotlib.pyplot as plt  
import random  
  
data = [ random.randint(5, 25) for x in range(0,20) ]  
  
plt.title(" Datos Aleatorios")       # el título 
plt.plot(data)                       # transmisión de los datos 
plt.ylabel('Etiqueta eje de las Y')  # título del eje Y  
plt.xlabel('Etiqueta eje de las X')  # título del eje X  
plt.show()                           # Visualización 

Y nuevamente, agregamos un título al gráfico y le damos etiquetas a los dos ejes.

Esto es lo que da:

images/imagen_2.png

Ocho líneas de código en total. Difícil de conseguir algo más...

Las expresiones regulares (parece magia)

Las expresiones regulares o racionales han formado parte del sistema Unix desde sus inicios.

Originalmente, se trata de una teoría matemática para describir conjuntos. El propio Ken Thompson (uno de la diseñadores de Unix), la implementó en el editor ’ed’, y después en ’grep’.

Larry Wall integró en su lenguaje Perl, operadores específicos para expresiones regulares. Esto le da a este lenguaje un poder incomparable, pero en detrimento de la legibilidad del código.

Aclaración del autor: “Esto no es una reseña, es mi humilde opinión y hablo por experiencia propia"

Desde entonces, todos los lenguajes informáticos permiten, de una forma u otra, el uso de esta gran herramienta.

Guido Van Rossum habría codificado expresiones regulares en Python tras un intercambio de ideas con Larry Wall.

Por otro lado, es casi seguro que para los no Unixianos o el común de los mortales, es más un encantamiento que programación.

Pero si es pragmático, este módulo le ahorra tiempo, porque le permite codificar ciertos scripts repetitivos más rápidamente.

Con las expresiones regulares, es posible expresar en unas pocas líneas un código que, de otra manera, requeriría varias decenas de líneas.

No hay nada complicado en la sintaxis de las expresiones regulares, y muchas veces solo tiene que probar y buscar para encontrar la solución. Algunas veces eso tiene un poco de mágico.

Como puede ver, las expresiones regulares son muy apreciadas por el autor y se puede encontrar una explicación a este entusiasmo en el anexo a este libro.

Python usa las expresiones regulares POSIX con algunas diferencias, pero no es importante.

Ahora que conoce la historia de las expresiones regulares, parece acertado ver qué puede hacer con ellas.

En primer lugar, una expresión regular es solo una cadena de caracteres que describe un patrón, que se aplica a otras cadenas de caracteres.

Esto hace posible determinar las cadenas de caracteres que coinciden con el patrón; este es el principio básico, pero va un poco más allá.

Gracias a este patrón que aplicamos a una cadena, con los métodos siguientes podemos:

re.match(patrón, cadena)

Saber si la cadena respeta el patrón....

Las fechas y el tiempo (regreso al futuro)

Quizás este es el módulo que marcará la diferencia si tiene que elegir entre un buen script antiguo bash y Python.

Realizar cálculos de fechas con el shell, aunque aún sea posible, no es tarea fácil, dado que no fue diseñado para eso y que a decir verdad, tampoco es su función.

Python necesitaba tener herramientas capaces de manejar fechas, tiempo e intervalos.

Estos módulos se denominan:

datetime

para la gestión de las fechas y del tiempo

dateutil

añade funcionalidades al módulo de fecha y hora

time

para la gestión del tiempo (en particular time.sleep)

calendar

le permite administrar un calendario, como el comando ’cal’ de Unix

Pero hay otras.

1. stdlib: calendar, datetime, dateutil, time

Primer problema: saber dónde está el método que le interesa en todos estos módulos.

Aquí hay una breve descripción de estos módulos:

datetime

Este módulo es el punto de partida para la gestión de fechas y tiempo.

La aritmética se basa en el número de días.

Los puntos fuertes son la transformación de cadena en fecha y viceversa.

dateutil

Este módulo agrega funcionalidades al módulo datetime, en particular en el cálculo dado en años/meses/días, una aritmética más "humana" como la suma de seis meses, por ejemplo.

También hay potentes funciones para el parsing de fechas y la gestión de TimeZones.

calendar

Aquí se encuentran las funciones para generar un calendario en formato HTML por ejemplo....

El módulo logging

Este módulo no será necesariamente útil, sobre todo al principio, aunque su uso sea sencillo.

Además, el tutorial sobre el registro de la documentación oficial en python.org es del mismo tipo de opinión. No es necesario un módulo de registro logging para un script simple; print() puede ser suficiente.

La mayoría de las veces, usamos el siguiente script de shell básico:

#archivo: base_script.sh  
## -------------------  
## Script básico  
## -------------------  
  
BASE_DIR=$(pwd) # o lo que quiera  
  
## +%j da el número del día del año  
## Permite tener un archivo por día y un historial de un año  
TS=$(date "+%j")  
LOG=$BASE_DIR/log/${TS}.log  
  
## Redirigimos los flujos estándar  
  
exec 2>&1  
exec 1>$LOG  
  
## -----------------------  
## Pequeña rutina de log  
## -----------------------  
log()  
{  
   msg="${1}"  
   ts=$(date "+%j %X")  
   printf ">>> ${ts}: ${msg}\n"  
}  
  
## Función principal  
compute()  
{  
   echo "Trabajo..."     # aquí insertar la llamada al script  
   sleep 5               # python shell u otro 
}  
  
  
## -----------  
## MAIN  
## -----------  
log "Inicio de la operación"  
calcula  
log "Fin de la operación" 

En el archivo se debe encontrar $BASE_DIR/log/nm_del_dia.log:

>>> 313 12:51:20: Inicio de la operación 
Trabajo...  
>>> 313 12:51:25: Fin de la operación 

Los ángulos ’>>>’ permiten segmentar logs grandes en etapas y encontrarlos...

El acceso a los archivos en modo binario y el módulo struct

Incluso si el acceso a los archivos en modo binario ya no está realmente de moda, es posible que nos encontremos frente a este tipo de problema a resolver y ahora que conocemos Python, pensamos que debe haber una solución.

El módulo struct está diseñado para transformar bytes a partir de una estructura que se expresará como un formato.

Ejemplo: el archivo ’/var/log/wtmp’ de su máquina Linux.

Su estructura se puede encontrar en la página de manual de wtmp y comienza así (traducido al español):

Tipo de registro

4 bytes

Nº de procesos

4 bytes

Nombre de dispositivo

Cadena en C de 32 caracteres máximo

Id Inittab

Cadena en C de 4 caracteres máximo

Usuario

Cadena en C de 32 caracteres máximo

...

 

Total 384 bytes

 

Entonces: hay 4 + 4 + 32 + 4 + 32 = 76 bytes y por lo tanto 308 para llegar hasta 384.

El uso del módulo struct es, como siempre, bastante simple.

Una vez definido el formato, se pueden aplicar los siguientes métodos:

  • calcsize(estructura) para calcular el tamaño del registro.

  • unpack(estructura, datos) para dividir los datos en función del formato.

  • pack (estructura, datos) para hacer lo contrario.

El script no es demasiado complejo: abrimos el archivo en modo binario y lo leemos en 384 bytes, que descomprimimos para recuperar datos utilizables.

Lo que da el siguiente...

La generación de datos aleatorios

Este módulo puede proporcionar muchos servicios siempre que nos tomemos el tiempo para interesarnos en él.

Su objetivo: proporcionar "buenos" datos falsos.

Faker (ese es su nombre) puede generar tantos datos falsos como sea necesario.

Hoy en día, la protección de datos debe ser un reflejo inmediato. Muchos clientes le han pedido al autor que firme una carta de confidencialidad en todo su sistema informático. Sin embargo, no se trata de sectores estratégicos como el militar o el nuclear.

Por tanto, ya no es posible copiar o tomar prestado un archivo de productos, ni siquiera una pequeña parte, para realizar pruebas.

Aquí es donde este módulo puede resultar útil: ¿Necesita estresar a su administrador de contactos? Faker puede generar 10.000… ¡todos falsos!

A continuación se muestra un pequeño ejemplo:

#archivo: fake1.py  
  
from faker import Factory  
fake = Factory.create()  
  
for i in range(1,10):  
   print(fake.name()) 

Y durante la ejecución:

Alexander Perez  
David Campbell  
Jeffrey Garcia  
Lynn James  
Ashley Marshall  
Walter Santana  
Shawn Rich  
Robert Evans MD  
Julie Johnson 

Son nombres que suenan estadounidenses, la localización por defecto; para...

El acceso a las bases de datos

Un lenguaje informático es una herramienta formidable para expresar algoritmos y manipular datos. Pero el lenguaje más bello del mundo solo puede dar lo que tiene.

Un script, programa o proceso no es nada sin datos y los datos, no son grancosa sin scripts, programas y procesos.

Todos los lenguajes pueden leer y escribir en archivos y en múltiples formatos. Pero como cada lenguaje tiene su propio método (y cada desarrollador también), muy pronto en la historia de la informática, apareció la necesidad de gestionar los datos por separado: de ahí la noción de base de datos.

Al inicio, los datos se almacenaban de manera secuencial en banda magnética.

Luego aparecieron los discos duros y esto permitió el almacenamiento de grandes cantidades de datos. Pero también permitió el acceso aleatorio a los datos y ya no secuencial.

A partir de ahí, las bases de datos se han convertido en la piedra angular de los sistemas de información.

Además, una de las tareas del ingeniero de sistemas es realizar una copia de seguridad de los datos. También debe hacer una copia de seguridad del sistema operativo, las configuraciones, etc., pero todo eso se puede reconstruir. Este no es el caso de los datos. Además, con los sistemas de gestión de bases de datos relacionales (RDBMS), es necesario garantizar la consistencia de estos datos.

En resumen, las bases de datos son importantes, pero eso ya lo sabía. Sin embargo, recuerde siempre que al final del día, una base de datos es solo para leer y escribir datos.

En la gran familia de las bases de datos, dos categorías destacan un poco más entre las demás.

Por un lado, las bases de datos relacionales, donde la información se debe almacenar en tablas bidimensionales, columnas y registros, comúnmente llamadas "tablas", que respetan el estándar ACID y utilizan el lenguaje SQL.

Este es el modelo básico más extendido.

ACID significa Atomicidad, Coherencia, Aislamiento y Durabilidad por sus siglas en inglés.

Por otro lado, las bases NoSQL, un conjunto de BDD (base de datos distribuida) con una forma diferente de ver las cosas: el almacenamiento de información está un poco menos estructurado, pero permite estar mucho más cómodo en determinados contextos, especialmente...

Los ORM u Object-Relationnal Mapping

Una base de datos relacional se parece mucho a un armario con cajones y cajas.

Los datos deben encajar. Si los datos no tienen el tamaño correcto, la base de datos los rechaza.

Pensar o codificar en modo "Objeto", es como guardar las compras en bolsas: a veces hay que mezclar ciertos objetos, hay bolsas para productos congelados, otras donde guardar ensaladas y huevos, que son más delicados. Algunas bolsas son pesadas porque solo contienen las botellas, etc. Y manejamos montones de objetos heterogéneos y similares.

¿Cómo pueden estos dos mundos interactuar de manera efectiva?

Después de todo, es muy posible que la comida acabe ordenada en los armarios, la nevera y el congelador.

El RDBMS (Sistema de gestión de Bases de datos relacionales) se debe acercar al objeto y el lenguaje-objeto debe hacer lo mismo.

Esta noción se llama ORM (Object Relationnal Mapping). En español: Asignación objeto- relacional.

El interés de un ORM radica en varios puntos.

El primero: le facilita la vida al desarrollador. Se encuentra administrando clases y no tablas, usa métodos de clase en lugar de lanzar consultas SQL.

El segundo (y debe haber otros): es la independencia de la base de datos. Un ORM funciona de la misma manera con SQLite, MySQL, PostgreSQL, Oracle, etc., con pocos o muy pocos cambios en el código.

En los ejemplos sobre bases de datos, recuerde el tratamiento de fechas específicas. Con un ORM, este problema desaparece.

Hay dos paradigmas principales de ORM: el Data Mapper pattern y el Active Record pattern.

Ambos presentan las tablas como una clase.

La diferencia es que con Active Record, la noción de escribir en la base de datos se encuentra a nivel de la clase, mientras que con Data Mapper Pattern hay que pasar por otra clase, un Manager, que representa la sesión con la base de datos.

Ejemplo Active Record

c = Contact()                  # creación de un nuevo contacto  
c.nombre = "Guido Van Rossum"  # asignación de campos  
c.tel = "06 01 02 03 04"  
c.save()                       # Escritura en la base de datos 

Ejemplo Data Mapper...

Red

Hasta ahora hemos aprendido cómo conectarnos a bases de datos, generar datos aleatorios, crear buenos archivos de registro, etc., sabemos que todo esto ocupará disco, RAM y CPU.

Es hora de ver qué podemos hacer con Python y la red.

Desde el principio, Python permite trabajar en los sockets e incluso directamente en el manejo de paquetes con la librería Scapy.

Escribir un servidor TCP y un cliente TCP con los sockets en Python se ha tratado miles de veces, y nos llevaría demasiado lejos. Estaríamos más cerca del desarrollo que del ’scripting’.

Por otro lado, el uso de ciertos protocolos de nivel superior con Python, en ocasiones permite responder de forma sencilla a problemas no siempre evidentes en shell.

Además, vamos a empezar con algo que ni siquiera es un script.

1. Un servidor web en una línea de comandos

No, el título de esta sección no es un error, y es posible crear un servidor web en una línea de comandos con un módulo de Python. Es suficiente con moverse a un directorio que contenga los archivos que quiere publicar y lanzar el siguiente comando:

python -m http.server 

Luego debe iniciar su navegador favorito y conectarse a http://localhost: 8000, eso es todo.

Siempre que haya un archivo index.html en el directorio donde se lanza el comando, tiene un entorno de prueba para páginas estáticas.

Tiene que transferir archivos de una máquina a otra, pero el servidor destino solo permite el flujo HTTP. Esta pequeña línea de comandos le permite hacer muchas cosas.

2. Enviar correos electrónico

Como de costumbre, con Python, enviar un correo electrónico es bastante fácil.

Creamos un objeto ’servidor de correo’ usando como parámetros un nombre de servidor o una dirección IP y un puerto; este objeto depende directamente de los protocolos de conexión del servidor de correo.

Luego, acordamos con el servidor el protocolo de envío de correo (EHLO).

En este punto, debe enviar los atributos de autenticación al servidor y finalmente, si los acepta, puede enviar el mensaje.

Sin embargo, todo depende de la configuración del servidor de correo.

Para ilustrar esta sección, preferimos hacerlo con un caso clásico cuando no hay un servidor de correo disponible o nadie puede decirle cuál usar: Gmail.

Necesitará una cuenta de Gmail para...

Python y la red de redes: Internet

Empieza a entenderlo: gracias a sus módulos, Python puede hacer muchas cosas. Hoy en día todo pasa por la red de redes, y allí también, Python tiene muchos recursos.

La World Wide Web ofrece una enorme cantidad de información y datos. Python, con algunos de los módulos presentados en esta sección, se está convirtiendo en una gran herramienta de "web scraping", que parece ser la palabra de moda en estos días.

Según Wikipedia: "La web scraping (a veces llamado harvesting), es una técnica para extraer contenido de sitios web, mediante un script o un programa, con el fin de transformarlo para permitir su uso en otro contexto".

1. Urllib: requests

Para convertirse en un buen "web scraper", debe comenzar desde el principio, es decir, por las peticiones del protocolo HTTP y su versión segura HTTPS.

En primer lugar, hay que tener cuidado porque hay muchos módulos que tratan el tema y es fácil perderse. La complejidad proviene del hecho de que todos estos módulos (urllib, urllib2, urllib3), funcionan de manera diferente y en diferentes versiones de Python.

Por esta razón vamos a presentar el módulo requests, basado en la librería urllib3, orgullosamente nombrada en su sitio como:

Requests necesita una instalación con pip.

Pequeño recordatorio: HTTP es un protocolo cuyo principio es, para el cliente (el navegador en general), enviar peticiones a un servidor HTTP, cuya finalidad es responder a sus peticiones.

Una petición HTTP especifica una acción (GET, POST…) sobre un recurso: la URL. El acrónimo URL (que significa Uniform Ressource Locator o localizador uniforme de recursos) se denomina más comúnmente "dirección web".

En una URL encontramos el protocolo de comunicación, el nombre del servidor y la ubicación del recurso en el servidor.

http://www.example.com/index.html

http:

Protocolo de comunicación HTTP

www.example.com

El nombre completo del sitio o FQDN, para Fully Qualified Domain Name

index.html

El recurso en el servidor

Para comprender cómo funciona Internet, un cortometraje lo resume todo en doce minutos. Busque en la red "Warrior of the net". Aunque datan de 1999, estas imágenes...

Herramientas

En esta sección, nos gustaría describir algunas herramientas y módulos que nos han sido útiles en unos cuantos casos concretos, aunque algunos están en gran parte desactualizados, pero nunca se sabe.

1. Pexpect

Expect es una herramienta antigua que también ha sido útil en su momento.

Esta herramienta permite ejecutar un binario y hablar con él. Permite automatizar tareas normalmente manuales.

Pexpect es un módulo de Python puro, construido sobre los mismos principios.

El uso es bastante sencillo: lanzamos el binario deseado, esperamos un prompt, enviamos algo, esperamos otra cosa, etc.

Tiene lugar un diálogo:

Espero (expect) ... recibo ... envío (send)...

Ejemplo con una conexión FTP

$ ftp speedtest.tele2.net  
Connected to speedtest.tele2.net.  
220 (vsFTPd 3.0.3)  
Name (speedtest.tele2.net:chris): anonymous  
331 Please specify the password.  
Password:  
230 Login successful.  
Remote system type is UNIX.  
Using binary mode to transfer files.  
ftp> ls  
200 PORT command successful. Consider using PASV.  
150 Here comes the directory listing.  
...  
-rw-r--r--    1 0        0         3145728 Feb 19  2016 3MB.zip 
-rw-r--r--    1 0        0       524288000 Feb 19  2016 500MB.zip 
-rw-r--r--    1 0        0        52428800 Feb 19  2016 50MB.zip 
-rw-r--r--    1 0        0          524288 Feb 19  2016 512KB.zip 
-rw-r--r--    1 0        0         5242880 Feb 19  2016 5MB.zip  
drwxr-xr-x    2 105      108         77824 Dec 15 17:25 upload  
226 Directory send OK.  
ftp> quit  
221 Goodbye. 

El sitio speedtest.tele2.net le permite descargar archivos de diferentes tamaños, para realizar pruebas.

Con pexpect, es más o menos lo mismo y se recomienda que haga las cosas manualmente antes de comenzar a desarrollar el código.

Comenzamos ejecutando un binario usando el método spawn, que devuelve un objeto ’procesos...

Resumen

Este capítulo le permite darse cuenta de la inmensidad del ecosistema Python.

También es por esta razón por lo que es difícil ser exhaustivo en librerías y herramientas de Python.

Y no se va a detener: la comunidad de Python crece todos los días.

La Programación Orientada a Objetos (POO) experimentó una edad de oro en el último siglo en la década de 1990; en ese momento, tenía que ser, como de costumbre la solución a todos los problemas.

La emoción ha disminuido un poco desde entonces, pero la POO no ha dejado de evolucionar.

El próximo capítulo analiza algunos conceptos esenciales en POO, pero también algunos conceptos y objetos del lenguaje Python que es necesario conocer.