Está en la página 1de 49

by

Ya
ko
19
76
id
en
ti.
io
Crear gráficos con python y matplotlib
Instalación de librerías
Gráficos básicos de lineas
Gráficos de area
Gráficos en 3D
Gráficos tipo «Pie» o «Pastel»
Es un lenguaje interpretado pero, ¿Se puede compilar Python?
Usar Cython
Usar pyinstaller
Docker desde python
Instalando el paquete de api de docker
Por donde empezamos
Declaramos el docker usado
Crear contenedor y arrancarlos
Listar contenedores
Arrancar y parar contenedores
Listar imagenes
Trucos para scripts
Leer y escribir ficheros GZip
Crear fichero tar.gz
Ocultar el password al pedirlo por consola
Ejecutar comandos con pexpect
Codificar y decodificar un binario en base64 por chunks
Comprobar web
Sacar voz a partir de un texto
Reimportar modulo
Eliminar carácteres no alfanumericos
Eliminar elementos vacíos de una lista
Como usar en windows volume shadow copy con python
Como usar una libreria hecha en C con python
Levantar un servidor web
Otra forma de ejecutar print
Calcular direcciones IP
Trucos para formatear texto
Trucos de fechas y horas
Fecha y hora unix (timestamp) a fecha
Tiempo completo
Fecha y hora completo
Fecha y hora UTC
Saber el timestamp actual
Saber semana del año
Saber el día, el mes y el año
saber el tiempo en dias transcurrido entre dos fechas
Tail en python
Usar un fichero de configuración
Como manejar JSON
Web scraping básico
Crear gráficos con python y matplotlib
Matplotlib es una librería que nos ofrece muchas posibilidades de creación de gráficos desde python
a partir de arrays de datos. La web oficial de esta librería es: https://matplotlib.org/

Instalación de librerías
Para instalar matplotlib solo tenemos que ejecutar pip install matplotlib como se puede ver en esta
pantalla:
Para poder trabajar con los ejemplos que mostraremos a continuación también debemos instalar scipy
con el comando pip install scipy:

Y también debemos instalar python-tk en el caso de debian/ubuntu y similares se hace con apt install
python-tk:
Gráficos básicos de lineas
En este primer ejemplo vamos a hacer gráficos simples definiendo únicamente el eje «Y» con los
datos que queremos dibujar:

ger@ger:~$ python

Python 2.7.15rc1 (default, Apr 15 2018, 21:51:34)

[GCC 7.3.0] on linux2

Type "help", "copyright", "credits" or "license" for more information.

>>> from pylab import *

>>> plot([1,2,3,2,1,3,2,1,2,3,4,5,4,30,10,1])

[]

>>> xlabel('mi grafico')

Text(0.5,0,'mi grafico')
>>> title('titulo de mi grafico')

Text(0.5,1,'titulo de mi grafico')

>>> draw()

>>> savefig("mi-grafico1",dpi=300)

>>> close()

>>>

Con este código anterior se crea un gráfico en base a los datos definidos en la segunda linea (la que
empieza por plot). Para enseñaros el funcionamiento hemos creado un fichero python en
/tmp/grafico.py con este código y lo hemos ejecutado:

Aquí se puede ver que no existe el fichero hasta su ejecución:


Después de crear el gráfico al abrirlo, podemos ver esto:

Cambiando parte del código se puede hacer que se muestre una ventana GUI con el gráfico que
hemos generado, esto se hace con la sentencia draw() :
io
ti.
en
id
76
Si añadimos antes de draw() la sentencia grid(True) se mostrará la cuadricula de fondo. Para mostrar
la leyenda se debe añadir legend( (‘Etiqueta1’,), loc = ‘upper left’) donde «Etiqueta 1» es el texto a
mostrar:
19
ko
Ya
by
Si queremos complicar un poco mas el gráfico de lineas simples podemos añadir linea de tiempo y
una segunda linea de datos:
En el caso anterior hemos podido definir el color y el texto de la etiqueta de cada linea. Esto lo
hacemos modificando los parámetros «color» y «label». En este caso como hemos utilizado
legend(loc = ‘upper left’) la leyenda adquiere los valores del parámetro label de la sentencia plot().
En este caso se podía haber utilizado también legend( (‘Vlores 1′,’Valores2’), loc = ‘upper left’) pero
la sentencia utilizada es más cómoda ya que nos evitamos pasar parámetros y estos se adquieren de
forma automática.

Gráficos de area
Es tan simple como añadir la sentencia fill_between(time,valores2,color=»red») (donde también
definimos el color del relleno del área ) por cada linea de un gráfico simple:
Y este es el resultado del gráfico de área:
Gráficos en 3D
Con el siguiente código generamos un gráfico en 3D con los datos facilitados en X e Y, el eje X se
facilita en el primer parámetro de np.arange:

from pylab import *

from mpl_toolkits.mplot3d import Axes3D

fig = figure()

ax = Axes3D(fig)

X = np.arange(-8, 30, 0.50)

Y = np.arange(-8, 20, 0.50)

X, Y = np.meshgrid(X, Y)

R = np.sqrt(X**2 + Y**2)

Z = np.sin(R)
ax.plot_surface(X, Y, Z, rstride=1, cstride=1)

show()

El resultado es:

Si queremos cambiar el mapa de colores podemos modificar ax.plot_surface(X, Y, Z, rstride=1,


cstride=1) por ejemplo:
ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=’hot‘) esta sentencia establecerá unos colores
calidos y si queremos unos colores frios podemos utilizar «cool».

Gráficos tipo «Pie» o «Pastel»


En este último apartado enseñamos como generar un gráfico de pastel

from pylab import *

y = [1,2,3,2,1,3,2,1,2,3,4,5,4,30,10,1]

pie(y)

xlabel('mi grafico')

title('titulo de mi grafico')

legend( ('Etiqueta1',), loc = 'upper left')

draw()

#savefig("mi-grafico1",dpi=300)
#close()

grid(True)

show()

Si sustituimos pie(y) por plot(y) generamos un gráfico de lineas. Las lineas comentadas si se
descomentan, guardarán el gráfico directamente aparte de mostrarlo con show() . El resultado de este
código es:

Puedes encontrar mas información sobre como hacer otro tipo de gráficos como por ejemplo los de
barras en la documentación de la web oficial https://matplotlib.org/

Es un lenguaje interpretado pero, ¿Se puede compilar


Python?
Mucha gente se pregunta: ¿Se puede compilar python? La respuesta es no, y diréis, ¿Para que haces
un capítulo si no se puede? lo explico matizando por qué digo que no se puede:
Realmente python es un lenguaje interpretado por lo que no se puede compilar, pero hay varias
utilizades que nos pueden generar un ejecutable a partir de nuestro código python, ya sea standalone
o dependiente de librerías:

Usar Cython
1- La primera forma de crear un ejecutable a partir de nuestro script python es con la utilidad Cython,
la cual convierte el código a lenguaje C para posteriormente compilarlo con un compilador C como
puede ser GCC:

Script «test.py»

def testPython():

toprint = "Python mola"

print(toprint)

if __name__=="__main__":

testPython()
Para hacer lo siguiente es necesario instalar cython, se puede instalar con easy_install o con pip:

root@host:~# pip install cython

root@host:~#

Después transformamos el codigo python en C y compilamos con GCC:

root@host:~# cython --embed -o test.c test.py

root@host:~# gcc -I/usr/include/python2.7 -lpython2.7 -o test test.c

root@host:~#

Como se puede ver se crea el ejecutable y se comporta exactamente igual que el script:

root@host:~# ./test

Python mola

root@host:~# python test.py

Python mola

Como se puede ver, se ha generado un fichero ejecutable elf de linux (exe en windows), depende de
las librerías de python (y como en cualquier binario hay que tener cuidado de lo que se deja en los
strings ya que con el comando strings se puede obtener texto en claro):

root@host:~# file test

test: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-
64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=e54070acae5bb3d0c751b495919680933e43955f, not stripped

root@host:~# ldd test

linux-vdso.so.1 (0x00007ffea39cc000)

libpython2.7.so.1.0 => /usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0 (0x00007fdf70a44000)

libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fdf70699000)

libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007fdf7047e000)

libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fdf70261000)

libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fdf7005d000)

libutil.so.1 => /lib/x86_64-linux-gnu/libutil.so.1 (0x00007fdf6fe5a000)

libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fdf6fb59000)

/lib64/ld-linux-x86-64.so.2 (0x00007fdf70fc9000)

root@host:~# strings test|grep "Python"

testPython

Python mola
testPython

test.testPython

while calling a Python object

__pyx_k_testPython

__pyx_k_Python_mola

__pyx_kp_s_Python_mola

__pyx_n_s_testPython

__pyx_mdef_4test_1testPython

__pyx_pw_4test_1testPython

__pyx_pf_4test_testPython

Usar pyinstaller
También podemos crear un ejecutable con pyinstaller, aunque de esta forma realmente
empaquetamos el script python y sus librerías dentro de un binario, de esta forma no se requiere ni
python ni sus librerías instaladas en el sistema que se ejecute el binario generado:

Lo primero es instalar pyinstaller, se puede hacer con pip o con easy_install

root@host:~# pip install pyinstaller

root@host:~#

Después generamos el binario con:

root@host:~# pyinstaller -F test.py

23 INFO: PyInstaller: 3.2.1

23 INFO: Python: 2.7.9

24 INFO: Platform: Linux-3.16.0-4-amd64-x86_64-with-debian-8.10

24 INFO: wrote /tmp/test.spec

27 INFO: UPX is not available.

28 INFO: Extending PYTHONPATH with paths

['/tmp', '/tmp']

28 INFO: checking Analysis

28 INFO: Building Analysis because out00-Analysis.toc is non existent

28 INFO: Initializing module dependency graph...

29 INFO: Initializing module graph hooks...


61 INFO: running Analysis out00-Analysis.toc

74 INFO: Caching module hooks...

76 INFO: Analyzing /tmp/test.py

77 INFO: Loading module hooks...

77 INFO: Loading module hook "hook-encodings.py"...

1121 INFO: Looking for ctypes DLLs

1122 INFO: Analyzing run-time hooks ...

1125 INFO: Looking for dynamic libraries

1231 INFO: Looking for eggs

1231 INFO: Python library not in binary depedencies. Doing additional searching...

1260 INFO: Using Python library /usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0

1262 INFO: Warnings written to /tmp/build/test/warntest.txt

1290 INFO: checking PYZ

1290 INFO: Building PYZ because out00-PYZ.toc is non existent

1290 INFO: Building PYZ (ZlibArchive) /tmp/build/test/out00-PYZ.pyz

1440 INFO: Building PYZ (ZlibArchive) /tmp/build/test/out00-PYZ.pyz completed successfully.

1465 INFO: checking PKG

1465 INFO: Building PKG because out00-PKG.toc is non existent

1465 INFO: Building PKG (CArchive) out00-PKG.pkg

3070 INFO: Building PKG (CArchive) out00-PKG.pkg completed successfully.

3074 INFO: Bootloader /usr/local/lib/python2.7/dist-packages/PyInstaller/bootloader/Linux-64bit/run

3074 INFO: checking EXE

3074 INFO: Building EXE because out00-EXE.toc is non existent

3075 INFO: Building EXE from out00-EXE.toc

3075 INFO: Appending archive to ELF section in EXE /tmp/dist/test

3090 INFO: Building EXE from out00-EXE.toc completed successfully.

El fichero binario se ha generado en el directorio «dist/» y como se puede ver a continuación se


comporta igual que el script como el otro binario que hemos generado antes:

root@host:~# dist/test

Python mola

Como se puede ver, también se ha generado un fichero binario ELF (en windows un EXE) ,tiene
menos dependencias de librerias y no aparece nada de lo escrito en los strings cuando ejecutamos el
comando «strings»:

root@host:~# file dist/test

dist/test: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-
64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=373ec5dee826653796e927ac3d65c9a8ec7db9da, stripped

root@host:~# ldd dist/test

linux-vdso.so.1 (0x00007ffc22787000)

libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fc7ada4b000)

libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007fc7ad830000)

libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fc7ad485000)

/lib64/ld-linux-x86-64.so.2 (0x00007fc7adc4f000)

root@host:~# strings dist/test |grep Python

Py_SetPythonHome

Cannot dlsym for Py_SetPythonHome

Error loading Python lib '%s': %s

Error detected starting Python VM.

Otra cosa a tener en cuenta es que el tamaño del fichero ejecutable será mayor con esta utilidad ya
que se ha generado un fichero standalone y para eso se han incluido las librerias necesarias en el
código:

root@host:~# ls -alh test

-rwxr-xr-x 1 root root 48K feb 15 01:24 test

root@host:~# ls -alh dist/test

-rwxr-xr-x 1 root root 3,6M feb 15 01:35 dist/test

Docker desde python


Docker es un sistema de virtualización basado en contenedores. Es muy potente y versátil. Y hoy os
enseñamos a utilizar su API desde python para integrarlo en vuestros desarrollos y scripts. Incluso
para poder haceros vuestro propio orquestador (aunque para esto puede interesar mas kubernetes,
pero de esto ya hablaremos).

Desde la API de docker para python se pueden realizar una gran variedad de operaciones. Se pueden
crear contenedores, manejar los existentes, gestionar imágenes, etc.
Vamos por partes:

Instalando el paquete de api de docker


Partimos de la base de que ya tenemos docker instalado en el sistema (si no es así podemos ver como
hacerlo en el articulo https://aprendeit.com/como-empezar-con-docker/ ). Por lo que el siguiente paso
es instalar con pip el paquete de la API de docker.

Para empezar debemos instalar pip si no lo tenemos instalado.

En Centos 7:

# yum install epel-release

# yum -y install python-pip

En Debian:

# apt-get instal python-pip

Una vez instalado pip, instalamos el modulo de python «docker»:

root@host :~# pip install docker

Collecting docker

Downloading
https://files.pythonhosted.org/packages/e1/58/938fbc7acd98302ca4872f5eab8ab811498e342ab5aec0c1609f22e0aeda/docker-
3.6.0-py2.py3-none-any.whl (131kB)

100% |████████████████████████████████| 133kB 989kB/s

Requirement already satisfied: backports.ssl-match-hostname>=3.5; python_version < "3.5" in


/usr/local/lib/python2.7/dist-packages (from docker) (3.5.0.1) Requirement already satisfied: docker-pycreds>=0.3.0
in /usr/local/lib/python2.7/dist-packages (from docker) (0.4.0)

Requirement already satisfied: ipaddress>=1.0.16; python_version < "3.3" in /usr/lib/python2.7/dist-packages (from


docker) (1.0.17) Requirement already satisfied: requests!=2.18.0,>=2.14.2 in /usr/local/lib/python2.7/dist-packages
(from docker) (2.19.1)

Requirement already satisfied: six>=1.4.0 in /usr/lib/python2.7/dist-packages (from docker) (1.11.0)

Requirement already satisfied: websocket-client>=0.32.0 in /usr/local/lib/python2.7/dist-packages (from docker)


(0.54.0)

Requirement already satisfied: idna<2.8,>=2.5 in /usr/lib/python2.7/dist-packages (from requests!=2.18.0,>=2.14.2-


>docker) (2.6)

Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python2.7/dist-packages (from


requests!=2.18.0,>=2.14.2->docker) (2018.8.24)

Requirement already satisfied: chardet<3.1.0,>=3.0.2 in /usr/local/lib/python2.7/dist-packages (from


requests!=2.18.0,>=2.14.2->docker) (3.0.4)

Requirement already satisfied: urllib3<1.24,>=1.21.1 in /usr/local/lib/python2.7/dist-packages (from


requests!=2.18.0>=2.14.2->docker) (1.23)
Installing collected packages: docker

Successfully installed docker-3.6.0

Ahora que ya tenemos instalado el modulo de python para trabajar con docker podemos empezar:

Por donde empezamos


Todo lo que vamos a hacer ahora se puede hacer desde la consola de python o desde un script, en este
caso lo orientaremos a un script.

Declaramos el docker usado


En primer lugar debemos declarar cual es el docker que vamos a usar esto se puede hacer de varias
formas:

import docker

client = docker.DockerClient(base_url='unix://var/run/docker.sock')

Otra forma de declararlo es:

import docker

client = docker.from_env()

Crear contenedor y arrancarlos


Para crear contenedores y para todas las demás operaciones que mostraremos siempre debemos
declarar primero el docker usado. Después llamaremos al método run, los parámetros son:
run(IMAGE,name=»NOMBRE DEL CONTENEDOR», tty=True,detach=True, stdin_open=True ).
Si la imagen no está descargada tardará un poco mas, mas adelante veremos como listar las imágenes
disponibles.

import docker

#Declaramos declaramos el docker usado

client = docker.from_env()

client.containers.run("centos:7",name="Prueba1", tty=True, detach = True, stdin_open = True)

Listar contenedores
Cuando solicitemos el listado nos devolverá un array con los IDs de los contenedores generados. Al
hacerlo con containers.list() es igual que si hiciesemos docker ps, solo nos muestra los levantados,
para ver todos, es necesario ejecutarlo con el parámetro all=True, es decir
client.containers.list(all=True)

import docker

#Declaramos declaramos el docker usado

client = docker.from_env()

lista = []

lista = client.containers.run("centos:7",name="Prueba1", tty=True, detach = True, stdin_open = True)

#Nos devolverá un array de objetos container como: [,]

Aquí se puede ver un ejemplo:

Arrancar y parar contenedores


A partir de una lista de contenedores, podemos trabajar sobre ellos, apagandolos, eliminándolos y
arrancándolos.

import docker

#Declaramos declaramos el docker usado

client = docker.from_env()

lista = []

lista = client.containers.list(all=True)

for contenedor in lista:

io
print("su id es {0} y su nombre {1} ".format(contenedor.id,contenedor.name))

ti.
print(contenedor.status)

en
contenedor.stop()

lista = client.containers.list(all=True)

for contenedor in lista:


id
76
print(contenedor.status)

contenedor.start()
19

lista = client.containers.list(all=True)
ko

for contenedor in lista:


Ya

print(contenedor.status)

contenedor.status()

En el anterior código hacemos varios bucles para actualizar el estado, el resultado sería:
by

[root@dev ~]# python

Python 2.7.5 (default, Jul 13 2018, 13:06:57)

[GCC 4.8.5 20150623 (Red Hat 4.8.5-28)] on linux2

Type "help", "copyright", "credits" or "license" for more information.

>>> import docker

>>> #Declaramos declaramos el docker usado

... client = docker.from_env()


>>>

>>> lista = []

>>> lista = client.containers.list(all=True)

>>> for contenedor in lista:

... print("su id es {0} y su nombre {1} ".format(contenedor.id,contenedor.name))

... print(contenedor.status)

... contenedor.stop()

...

su id es 0f5278995d793e6627ec1086094a38052e83089ee43fa150ed8e1fb55c6d6c0a y su nombre Prueba1

running

>>> lista = client.containers.list(all=True)

>>> for contenedor in lista:

... print(contenedor.status)

... contenedor.start()

...

exited

>>> lista = client.containers.list(all=True)

>>> for contenedor in lista:

... print(contenedor.status)

... contenedor.status()

...

running

Para eliminar un contenedor, primero debe estar parado y podemos hacerlo como hacemos con
«.stop()» pero ponemos en su lugar «.remove()«.

Listar imagenes
Para ver las imágenes se parece bastante a como lo hacemos con los contenedores, se llama al
método «.list()» de images:

import docker

#Declaramos declaramos el docker usado

client = docker.from_env()
lista = []

lista = client.images.list()

for image in lista:

print(image.id)

print(image.tags)

#Nos devolverá un array de objetos image con los datos de las imagenes locales

Por ejemplo:

[root@dev ~]# python

Python 2.7.5 (default, Jul 13 2018, 13:06:57)

[GCC 4.8.5 20150623 (Red Hat 4.8.5-28)] on linux2

Type "help", "copyright", "credits" or "license" for more information.

>>> import docker

>>> #Declaramos declaramos el docker usado

... client = docker.from_env()

>>>

>>> lista = []

>>> lista = client.images.list()

>>> for image in lista:

... print(image.id)

... print(image.tags)

... #Nos devolverá un array de objetos image

...

sha256:1e1148e4cc2c148c6890a18e3b2d2dde41a6745ceb4e5fe94a923d811bf82ddb

[u'docker.io/centos:7']

sha256:dc496f71dbb587a32a007a0ffb420d1b35c55ec31cda99c0f5336954623f8368

[u'docker.io/alpine:3.5']

sha256:174b26fe09c724368aa2c3cc8f2b979b915a33f7b50c94cd215380d56147cd60

[u'docker.io/alpine:3.4']

sha256:c78b5648029c3636a0c6d056eeba8c3a2e970976342ee156155db19ca81c6f5e

[u'docker.io/alpine:3.3']
sha256:4558d96d24b5acf7d9bdaa060124ae787fa38093eb00538b88378833de5a223d

[u'docker.io/alpine:3.2']

sha256:f36c4228b2c6863208de3a13f2e467476d00ab492416c0aadcfc0e247db1ee03

[u'docker.io/alpine:3.1']

sha256:de4761d9f0371cbace6a4c2ebef14b14ce30185a7fcedb5e04b170130e7e642d

[u'docker.io/alpine:edge']

sha256:196d12cf6ab19273823e700516e98eb1910b03b17840f9d5509f03858484d321

[u'docker.io/alpine:3.8', u'docker.io/alpine:latest']

sha256:34ea7509dcad10aa92310f2b41e3afbabed0811ee3a902d6d49cb90f075fe444

[u'docker.io/alpine:3.7']

sha256:94627dfbdf19f1344aae6ef72db6ff30c5148b60e1091de098807ec4b42febbc

[u'docker.io/alpine:3.6']

sha256:b1666055931f332541bda7c425e624764de96c85177a61a0b49238a42b80b7f9

[u'docker.io/bfirsh/reticulate-splines:latest']

sha256:93f518ec2c41722d6c21e55f96cef4dc4c9ba521cab51a757b1d7272b393902f

[u'docker.io/alpine:2.7']

sha256:e738dfbe7a10356ea998e8acc7493c0bfae5ed919ad7eb99550ab60d7f47e214

[u'docker.io/alpine:2.6']

Y esto es solo una pequeña parte de lo que se puede llegar a hacer, puede consultarse toda la
información sobre la librería en https://docker-py.readthedocs.io/en/stable/client.html ya que es la
web oficial.

Trucos para scripts

Leer y escribir ficheros GZip


En ocasiones tenemos que crear ficheros GZip de algún fichero mas grande o es posible que
tengamos que transferir datos. Esta es la forma más sencilla de crear ficheros GZip. Es como crear un
fichero de texto pero importando el módulo gzip:

f = gzip.open(indexpath, 'rb')

import gzip

contenido = "Texto"

f = gzip.open(indexpath, 'rb')
data = f.read()

f.close()

Para leerlo es exactamente igual de fácil, al igual que en las escritura es la misma forma de de
trabajar que cuando creamos ficheros con python:

import gzip

f = gzip.open(indexpath, 'rb')

data = f.read()

f.close()

Crear fichero tar.gz


Al igual que en el ejemplo anterior crearemos un fichero GZip pero a partir de un directorio en vez
de a partir de a partir de un fichero. En este ejemplo crearemos un fichero tar.gz en el directorio
home del usuario actual incluyendo en el fichero el directorio .ssh que se encuentra también en el
directorio home del usuario actual:

from shutil import make_archive

import os

archive_name = os.path.expanduser(os.path.join('~', 'miarchivo'))

root_dir = os.path.expanduser(os.path.join('~', '.ssh'))

make_archive(archive_name, 'gztar', root_dir)

Ocultar el password al pedirlo por consola


En este ejemplo enseñamos como ocultar el password al pedirlo por consola en uno de nuestros
scripts. Esto es útil para evitar que se muestre. Se comportará exactamente como lo hace los
comandos passwd o su o sudo al pedir la password.
El código es el siguiente:

import getpass

usuario = raw_input("Introduce usuario: ")

password = getpass.getpass("Introduce password: ")

print(usuario, password)

Se mostraría lo siguiente:
Ejecutar comandos con pexpect
Este módulo es la versión para python de expect. Básicamente es capaz de Ejecutar un comando y
según la salida del comando introducir un texto en la consola. Esto es válido al utilizar comandos que
requieren de un tiempo de espera para introducir parámetros como por ejemplo passwd o ssh. De esta
forma se puede completar la ejecución del comando de forma correcta introduciendo los parámetros
necesarios, en el ejemplo mostraremos como ejecutar SSH introduciendo la contraseña dell host de
destino con pexpect:

import pexpect

import time

cmd = "ssh root@192.168.1.165"

child = pexpect.spawn(cmd)

child.expect('password:', timeout=10)

child.sendline(PASSWORD)

time.sleep(5)

child.sendline("ping -c1 192.168.1.1\n")

time.sleep(5)
child.sendline("\n")

fout = file('/tmp/texto-192.168.1.165','w')

child.logfile = fout

time.sleep(5)

child.expect(pexpect.EOF)

Lo que veríamos en la ejecución sería lo siguiente:


Y el fichero de log sería:
Codificar y decodificar un binario en base64 por chunks
Estos códigos permiten codificar y decodificar ficheros en base64, es útil para transferir ficheros de
gran tamaño o para transferir ficheros binarios o guardar firmas de virus, etc:
La forma de codificarlo sería la siguiente, en la cual estamos codificando un binario del comando
ping guardado en /tmp:

import codecs

import binascii

byte = "1"
in_file = open("/tmp/ping","rb")

out_file = open("/tmp/ping.b64","wb")

while byte != "":

byte = in_file.read(128)

encode = codecs.encode(binascii.b2a_base64(byte),"base64")

out_file.write("__INICIO__" + encode[0:(len(encode)-2)] )

in_file.close()

out_file.close()

Como se puede ver en el código anterior, se abre el fichero de origen y el de destino. Lee un bloque
del fichero de origen, codifica cada el bloque y lo guarda en el fichero de destino.
En el siguiente bloque de código, hace justo lo contrario. Es decir abre el fichero codificado, lo
decodifica y escribe en el fichero de destino. Todo esto bloque a bloque.

import codecs

import binascii

byte = "1"

in_file = open("/tmp/ping.b64","rb")

out_file = open("/tmp/ping.devuelta","wb")

count = 0

while byte != "":

byte = in_file.read(244)

print byte

if len(byte) != 244:

byte = byte[0:len(byte)-1]

if byte[0:10] == "__INICIO__":

byte = byte.replace("__INICIO__","")

print "Entra1"

out_file.write(binascii.a2b_base64(codecs.decode(byte+"=","base64")))

else:

bytes = byte.split("__INICIO__")

for b in bytes:
print b

out_file.write(binascii.a2b_base64(codecs.decode(b+"==","base64")))

in_file.close()

out_file.close()

Comprobar web
Este bloque de código ayuda a ver si una web tiene problemas. En este caso se comprueba solo
durante 10 minutos pero retocando el código se puede comprobar de forma infinita:

import requests,time,sys

def getWeb(url):

r = requests.get(url)

return int(r.status_code)

def main():

url = "http://google.es" #sys.argv[1]

counter = 0

status = getWeb(url)

print ("The website returns status code: {0}".format(status))

while counter&lt;10 and status==500:

status = getWeb(url)

print ("The website returns status code: {0}".format(status))

time.sleep(60)

counter += 1

if status==500:

print ("The website is down")

elif status==200:

print ("The website is OK")

else:

print ("The website is not returning error code 500 but is not OK")
if __name__=="__main__":

main()

Sacar voz a partir de un texto


Por desgracia todavía no tengo una alternativa para linux, solo tengo disponible este código para
windows.
Este código reproduce el texto que se le pasa como parámetro como un sonido:

#!/usr/bin/env python

# -*- coding: utf-8 -*-

import win32com.client

speaker = win32com.client.Dispatch("SAPI.SpVoice")

while True:

print("Introduzca el texto a reproducir:")

s = raw_input()

speaker.Speak(s)

Reimportar modulo
En ocasiones se tiene que recargar un módulo en tiempo de ejecución, esto se consigue con:

reload(modulo)

Con esta linea podemos hacer que si hemos creado un servicio, este recargue modulos en tiempo de
ejecución, para recargar posibles cambios en módulos o plugins sin reiniciar el servicio.

Eliminar carácteres no alfanumericos


Este código reemplaza los carácteres no alfanumericos por el carácter que deseemos, esto puede
servirnos por ejemplo de filtro para passwords:

import re

s = re.sub('[^0-9a-zA-Z]+', '*', s)

Eliminar elementos vacíos de una lista


A veces cuando reeplazamos elementos de una lista o hacemos un split de un texto puede pasar que
se nos generen elementos de la lista vacíos en decir: [»]. Esto puede solucionarse eliminando estos
elementos con el siguiente código:

texto="Prueba con espacios multiples"

io
str_list=texto.split(" ")

ti.
#este es el mas rapido

str_list = filter(None, str_list) # fastest

en
#O podemos utilizar este:

str_list = filter(bool, str_list) # fastest

#Este es otra opcion: id


76
str_list = filter(len, str_list) # a bit slower

#O este otro:
19

str_list = filter(lambda item: item, str_list) # slower than list

Aquí podemos ver como funciona:


ko
Ya
by
Como usar en windows volume shadow copy con
python
No son pocas veces las que se ha hablado de VSS (volume shadow copy de Windows) y las ventajas
y riesgos que conlleva. En esta ocasión vamos a hablar de como se puede realizar un backup de
cualquier fichero de windows tanto del sistema como del usuario. Hay muchos ficheros que no
pueden ser leídos y escritos al estar en zonas protegidas del sistema, con VSS(volume shadow copy
de Windows) ese problema no existe ya que los ficheros no están ubicados en la zona restringida del
sistema y la protección está desactivada para ellos.

import win32com.client

import os

from shutil import copyfile

def vssList():

wcd=win32com.client.Dispatch("WbemScripting.SWbemLocator")

wmi=wcd.ConnectServer(".","root\cimv2")

obj=wmi.ExecQuery("SELECT * FROM win32_ShadowCopy")


return [x.DeviceObject for x in obj]

def vssCreate():

wmi=win32com.client.GetObject("winmgmts:\\\\.\\root\cimv2:Win32_ShadowCopy")

createmethod = wmi.Methods_("Create")

createparams = createmethod.InParameters

createparams.Properties_[1].value="c:\\"

results = wmi.ExecMethod_("Create",createparams)

return results.Properties_[1].value

if __name__ == "__main__":

print(vssCreate())

list = vssList()

copyfile("{0}\\Windows\\System32\\drivers\\etc\hosts".format(list[0]), "c:\\nuevo")

Con este código se puede implementar un sistema de copias de seguridad a partir de los VSS de
windows utilizando el metodo « vssCreate() ».
También puede servir como forma de hacerse persistente en un sistema tras explotarlo, ya que
muchos antivirus no incluyen por defecto en sus escaneos del sistema los VSS.
Esto puede usarse de la siguiente forma tras explotar el sistema:
1-Se compromete el sistema y se copia el binario a la ubicación definitiva
2-Se lanza la creación de VSS (volume shadow copy de Windows)
De esta forma ya tenemos una copia «segura» del binario malicioso en el sistema.
Esto también es usado por los ransomware, lo que hacen es lanzar una copia con VSS y cifrar los
ficheros a partir de esta borrando los originales del disco. De modo que en ocasiones es posible
recuperar los ficheros a partir de estos VSS si hemos sido infectados por unos de estos malwares y
estos malwares no borran los VSS después de cifrar los ficheros.
Es importante que si un sistema ha sido infectado y se va a «limpiar» y a seguir usando (yo no so
partidario de esto, soy partidario de reinstalar) le purguen los VSS para evitar que resurja el
problema.

Como usar una libreria hecha en C con python


A veces un lenguaje de programación como python (aunque potente y versátil) puedes necesitar mas
potencia o accesos a librerías del sistema. Para hacer uso de una librería dinámica tipo .DLL
(windows) o .SO (linux) puedes hacerlo de la siguiente forma:
-En este caso vamos a crear una librería de prueba en C para linux (el mismo codigo de C y python se
puede usar en Windows).
Primer paso, creamos la libreria con el siguiente código de lenguaje C :

user@host:~$ cat testintegration.c

#include <stdio.h>

#include <stdlib.h>

#ifdef _WIN32

# define DLL_EXPORT __declspec(dllexport)

#else

# define DLL_EXPORT

#endif

DLL_EXPORT int sum(int a, int b) {

int res = 0;

res = a + b;

printf("ResC: %d\n",res) ;

return res;

Para compilarlo usamos el siguiente comando (sustituir librería por el nombre que se quiera):
user@host:~$ gcc -Wall -Wextra -O -ansi -pedantic -fPIC -shared LIBRERIA.c -o
/tmp/LIBRERIA.so
Para usarla en este lenguaje solamente hay que llamarla importando la clase cdll del modulo ctypes,
depués de usar el método LoadLibrary de la clase cdll, podremos llamar a los métodos de la librería
importada:

user@host:~$ python

Python 2.7.9 (default, Jun 29 2016, 13:08:31)

[GCC 4.9.2] on linux2

Type "help", "copyright", "credits" or "license" for more information.

>>> from ctypes import cdll;

>>> mydll = cdll.LoadLibrary('/tmp/LIBRERIA.so')


>>> mydll.sum(2,'a')

ResC: 1456018974

1456018974

Levantar un servidor web


En ocasiones necesitamos levantar un servidor web para transferir ficheros de forma rápida. Por
ejemplo si queremos descargar ficheros de un sistema linux sin instalar ningun servicio adicional
podemos utilizar el comando:

python -m SimpleHTTPServer 2048

Donde 2048 es el puerto. Es tan alto porque algunos sistemas operativos no dejan que un usuario deje
aplicaciones a la escucha en puertos inferiores al 1000.
Un ejemplo de uso es el siguiente:

Después de ejecutar esas lineas de comandos podremos acceder vía web a http://localhost:2048
como se puede ver en la siguiente imagen:
Como hacer que nuestro código sea multitarea
En ocasiones necesitamos que nuestro código ejecute varias tareas simultaneas. Se puede hacer de
multiples formas pero una de ellas es la siguiente:

import thread, time

def test(thname):

for i in range (1,10000):

print ((thname,i))

time.sleep(1)

thread.start_new_thread( test, ("cacota1",))

thread.start_new_thread( test, ("cacota2",))

while True:

print("test123")
time.sleep(5)
Otra forma de ejecutar el código multithread es:

import threading, time

def test(thname):

for i in range (1,10000):

print ((thname,i))

time.sleep(1)

def test1(arg):

while True:

print "test1"

time.sleep(1)

t1=threading.Thread( target=test, args=("texto1",))

t2=threading.Thread( target=test1,args=(None,))

t1.start()

t2.start()

while True:

print("test123")

time.sleep(5)

Otra forma de ejecutar print


El comando print() tiene la desventaja de que incluye saltos de linea y que no se puede definir el tipo
de salida (estandar, error, etc). Una alternativa a print() es:

sys.stdout.write(TEXTO)

sys.stdout.flush()

Se puede hacer tambien por la salida de error ejecutando lo siguiente:

sys.stderr.write(TEXTO)

sys.stderr.flush()
Calcular direcciones IP
Si estamos trabajando con direcciones IP y queremos saber si una IP pertenece a un rango podemos
ejecutar lo siguiente:

from ipcalc import IP, Network

if '10.0.0.10' in Network('10.0.0.0/8'):

print "OK"

for x in Network('10.2.32.40/27'):

print str(x)

En la primera parte miramos si la IP 10.0.0.10 pertenece al rango 10.0.0.0/8. Si es así imprime OK.
En la segunda imprime por pantalla todas las direcciones del rango 10.2.32.40/27

Trucos para formatear texto


Definir un diccionario y usarlo para dar formato:

>>> data = {'fruta ': 'pera', 'verdura ':'lechuga '}

>>> a = "Somos los mejores: {fruta} y {verdura}".format(**data)

>>> print a

Somos los mejores: pera y lechuga

Definir variables y usarlas en el texto:

>>> 'fruta '= 'pera'

>>> 'verdura '='lechuga '

>>> a = "Somos los mejores: {fruta} y {verdura}".format(

fruta=fruta, verdura=verdura

>>> print a

Somos los mejores: pera y lechuga

Trucos de fechas y horas

Fecha y hora unix (timestamp) a fecha


Para convertir un timestamp a fecha en texto se puede utilizar el siguiente código:
import datetime

temp = datetime.datetime.fromtimestamp(1386181800).strftime('%Y-%m-%d %H:%M:%S')

print temp

Tiempo completo
Para saber el tiempo actual podemos usar el siguiente código:

import time

time.ctime()

Fecha y hora completo


Si queremos tener la fecha y la hora actual desde python se puede hacer con el siguiente código:

import datetime

print(datetime.datetime.now())

Fecha y hora UTC


Para conocer la fecha y hora UTC:

import datetime

datetime.datetime.utcnow()

Saber el timestamp actual


Si queremos conocer el timestamp o fecha unix actual, ejecutaremos el siguiente código:
import time

time.time()

get date

import datetime

today = str(datetime.date.today()).split("-")

Saber semana del año


Para conocer la semana del año actual:
import datetime

today = datetime.date.today()

datetime.date(today.year,today.month, today.day).isocalendar()

Saber el día, el mes y el año


import datetime

today = datetime.date.today()

day = today.day

month = today.month

year = today.year

print (day,month,year)
saber el tiempo en dias transcurrido entre dos fechas
import datetime

dtime = datetime.datetime.utcnow() - datetime.datetime(2018, 3, 26, 23, 2, 1)

dtime.days

Tail en python
Leer ultimas lineas de un fichero cada vez que se actualice el fichero

from pygtail import Pygtail

io
for line in Pygtail("some.log"):

ti.
sys.stdout.write(line)

en
Usar un fichero de configuración
Puedes usar el módulo ConfigParser, pero antes tendrías que cambiar un poco tu archivo de
configuración ya que ConfigParser trabaja con secciones.
Archivo de ejemplo example.conf:
id
76
[HORAS]
19

hora_ini = 14:00

hora_fin = 22:00
ko

Con el archivo de ejemplo example.conf, tu script se podría ver así:

import ConfigParser
Ya

config = ConfigParser.ConfigParser()
by

config.read('example.conf')

hora_ini = config.get('HORAS', 'hora_ini')

hora_fin = config.get('HORAS', 'hora_fin')

print hora_ini

print hora_fin

Como manejar JSON


Como cargar json en una lista:

import json
jsonlist = json.loads(data)

Leer JSON de fichero:

import json

json_data=open(file_directory).read()

data = json.loads(json_data)

pprint(data)

Usar requests para hacer consultas http


Para hacer una query ejecutamos:

import json, requests

url = 'http://URL

resp = requests.get(url=url)

print(resp.text)

Si queremos leer un json de la respuesta de la petición http:

import json, requests

url = 'http://maps.googleapis.com/maps/api/directions/json'

params = dict(

origin='Chicago,IL',

destination='Los+Angeles,CA',

waypoints='Joplin,MO|Oklahoma+City,OK',

sensor='false'

resp = requests.get(url=url, params=params)

data = json.loads(resp.text)
Crear enlace simbolico
Para crear un enlace simbolico desde python utilizamos:

import os

os_symlink = getattr(os, "symlink", None)

if callable(os_symlink):

pass

else:

def symlink_ms(source, link_name):

import ctypes

csl = ctypes.windll.kernel32.CreateSymbolicLinkW

csl.argtypes = (ctypes.c_wchar_p, ctypes.c_wchar_p, ctypes.c_uint32)

csl.restype = ctypes.c_ubyte

flags = 1 if os.path.isdir(source) else 0

if csl(link_name, source, flags) == 0:

raise ctypes.WinError()

os.symlink = symlink_ms

Convertir BSON a JSON


Cuando consultamos a MongoDB queremos poder manejar los datos, para ello podemos convertirlas
en JSON:
>>> r = collection.find() # returns an object of class 'Cursor'

Then I convert to a list

>>> l = list(r) # returns a 'list' of 'dict'

here is what print(l) returns:

>>> [{u'date': datetime.datetime(2009, 11, 10, 10, 45), u'_id': 1, u'name': u'name1', u'value': 11},{u'date':
datetime.datetime(2013, 11, 10, 10, 45), u'_id': 2, u'name': u'name2', u'value': 22}]
>>> from bson.json_util import dumps

>>> dumps(l)

Mandar email
Enviar un correo desde un servidor SMTP local:
import smtplib #Envio de correo

def sendMail( subject, msgtxt, to): #envia mail

try:

from email.mime.text import MIMEText

msg = MIMEText(" [" + machine.name + "]\n"+msgtxt)

me = "email@dominio.com"

msg['Subject'] = subject

msg['From'] = me

msg['To'] = to

s = smtplib.SMTP('localhost')

s.sendmail(me, [machine.email], msg.as_string())

s.quit()

except Exception as e:

print("Error enviando: {err}".format(err=e))

Argparse basico
Argparse es una libreria para gestionar los puntos de entrada y parametros:

import argparse

parser = argparse.ArgumentParser()

parser.add_argument("agent")

parser.add_argument("message")

args = parser.parse_args()

Web scraping básico


El web scraping es la forma de parsear datos del HTML de una web. A continuación pongo varios
ejemplos
Web scraping sin soporte JS

import requests

from bs4 import BeautifulSoup

response = requests.get(my_url)

soup = BeautifulSoup(response.text)

soup.find(id="intro-text")

Webscraping con soporte JS + Screenshot

#dryscrape use: https://gist.github.com/lionelyoung/dd8a3eae9e0adcf6ba4a82e5c1c5c46c

import dryscrape

from bs4 import BeautifulSoup

import sys

session = dryscrape.Session()

session.set_header("User-Agent", "Mozilla/5.0 (Windows NT 5.1; rv:41.0) Gecko/20100101 Firefox/41.0")

session.visit( "https://encuentratrabajoya.com/oferta.html?id=5b7d229a5ee2653dc7271f74")

#Iniciar el virtual desktop, requiere de: sudo apt install xvfb

if 'linux' in sys.platform:

# start xvfb in case no X is running. Make sure xvfb

# is installed, otherwise this won't work!

dryscrape.start_xvfb()

session.render('/tmp/google.png')

#fin de screenshot

response = session.body()

soup = BeautifulSoup(response,features="lxml")

print (soup.get_text())

#print soup.find(id="table_results_offer0")

También podría gustarte