26 jun. 2016

Crear datos JSON a partir de un diccionario en Flask (parte 1)

Los artículos anteriores sobre el microframework Flask lo pueden revisar en el siguiente enlace.

Este artículo se basa en un artículo  en inglés que se títula: How to create JSON in Python flask .

El código de este artículo lo pueden en contrar en gitlab en el siguiente enlace.


La idea es crear datos JSON a partir de un diccionario que maneja una lista de empleados, y se publica vía web por medio de flask.

El código de app.py se muestra a continuación:

#!/usr/bin/env python

#Se importa de flask a Flask, jsonify y json

from flask import Flask,jsonify,json

#Se crea la instancia de la aplicacion

app = Flask(__name__)

#Se tiene una lista de nombres

lista = ["John Doe","Jane Doe"]



#Se crea 



#Se define el decorador route donde se da la ruta del servidor web.

@app.route("/ListaEmpleados")

def ListaEmpleados():

    

    try:

     #inicializar la lista de empleados

     listaEmpleados = []



     #crear instancias para llenar la lista

     for i  in lista:

      datos = i.split(" ")

      listaEmpleados.append({'nombre': datos[0],'apellido': datos[1]})    

        # convertir en dato json al diccionario

        jsonStr = json.dumps(listaEmpleados)



    except Exception ,e:

        print str(e)



    #Retorna el json



    return jsonify(Empleados=jsonStr)





if __name__ == '__main__':

 app.run()





Ahora se ejecuta:

python app.py

Se abre el navegador en http://localhost:5000/ListaEmpleados .

La siguiente figura muestra lo que devuelve el navegador:




En próximo artículo se continua con la parte de trabajar con el json.



16 jun. 2016

Ejecutar una prueba de integración continua con gitlab-ci y gitlab-runner

En artículos anteriores se explicó como usar gitlab-ce y gitlab-runner por medio de contenedores y conectarlos para la integración continua.

Para que funcione docker por medio de gitlab-runner es necesario modificar la configuración del runner agregando el nombre y la ip de la máquina como se muestra a continuación (archivo /etc/gitlab-runner/config.toml):

concurrent = 1

[[runners]]
  name = "Sample gitlab-ci cpp project"
  url = "http://12.168.0.60:9080t/ci"
  token = "5faac16d0aaf8f97fd66f5f586ed9f5f"
  executor = "docker"
  [runners.docker]
    tls_verify = false
    image = "debian"
    privileged = false
    disable_cache = false
    volumes = ["/cache"]
    extra_hosts = ["culata.dst:192.168.0.60"]
  [runners.cache]
    Insecure = false



Luego de modificar el archivo se ejecuta:
gitlab-runner restart

En el artículo del runner se tiene registrado un proyecto llamado sample-gitlabci-cpp-project tomado de github.

Contiene lo siguiente:

sample-gitlabci-cpp-project
├── helloworld.cpp
├── README.md
└── verify.sh


El archivo helloworld.cpp tiene lo siguiente:
// 'Hello World!' program 
 
#include <iostream>
 
int main()
{
  std::cout << "Hello World!" << std::endl;
  return 0;
}


El archivo verify.sh es el que genera la construcción:
#!/bin/bash

echo "Starting sample CI verification script"

echo "Trying to execute ./helloworld"

OUTPUT=`./helloworld`
RETVAL=$?

if [ $RETVAL -eq 0 ]; then
  echo "Retval is 0, OK"
else
  echo "Retval is not 0, FAIL"
  exit 1
fi

if [ "$OUTPUT" == "Hello World!" ]; then
  echo "Output is correct, OK"
else
  echo "Output is not right, FAIL"
  exit 1
fi


Se tiene otro archivo que está oculto con nombre .gitlab-ci.yml, que contiene el proceso de construcción del contenedor docker con la ejecución del verify.sh:

# Specify the docker image to use (only used if using docker runners)
# See: http://doc.gitlab.com/ee/ci/docker/using_docker_images.html
image: debian      

# Define commands that run before each job's script
before_script:
  - apt-get update
  - apt-get install -y gcc g++

# Try to compile our sample hello world app
compile:
  script:
  # Compile our app
  - g++ helloworld.cpp -o helloworld
  # Verify that our compiled app works properly with a custom "test" script
  - ./verify.sh
  # Save the compiled output from the above for downloading via GitLab and in Gitlab 8.6 to use in future build steps
  artifacts:
    paths:
    - helloworld


Ahora sólo queda ir a la sección build del proyecto y ejecutar un build, la siguiente figura muestra la ejecución del build como tal:


Como se ve en la figura la construción se dió sin problemas.

En siguientes artículos se mostrará el uso con node.js y con Django.

13 jun. 2016

Profiling de un script Python con cProfile

Hace un tiempo toque el tema de herramientas de profiling para Python (ver enlace).

Hay otras herramientas como cProfile que se pueden usar y son menos invasiva que las de los artículos anteriores, quiero decir, no necesitan modificar el código de la aplicación para que sea utilizada.

Como script de prueba usaré el mismo de raíz cuadrada que se encuentra en mi repo en github, el mismo de los artículos sobre pruebas unitarias, pruebas unitarias con docker, pruebas de documentación, pruebas de documentación con docker  y el de pylint con docker.

No se necesita instalar nada para usar cProfile.

El código del módulo raíz cuadrada es el siguiente:

#!/usr/bin/env python3

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



"""

Se importa el módulo math para calcular la raiz cuadrada.

"""

import math



#Función raiz cuadrada.

def Raiz(a):

    """Si a es mayor o igual a cero se calcula la raiz cuadrada"""

    if a >= 0:

        return math.sqrt(a)

    #Si es menor a cero se genera una excepción donde se informa que a debe ser mayor o igual a cero.

    else:

        raise ValueError("a debe ser >= 0")



if __name__ == '__main__':

    #Se importa el módulo doctest

    #import doctest

    #Se realiza la prueba al archivo raizcuadra.txt

    #doctest.testfile("raizcuadrada.txt")

    Raiz(5)

    Raiz(9)

    Raiz(25)

    #Raiz(-1)



Para ejecutar cProfile:

python -m cProfile -s cumtime raizcuadrada.py

         8 function calls in 0.000 seconds



   Ordered by: cumulative time



   ncalls  tottime  percall  cumtime  percall filename:lineno(function)

        1    0.000    0.000    0.000    0.000 raizcuadrada.py:6(<module>)

        3    0.000    0.000    0.000    0.000 raizcuadrada.py:10(Raiz)

        3    0.000    0.000    0.000    0.000 {math.sqrt}

        1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof.Profiler' objects}




Esto mismo se puede ejecutar desde el contenedor que se usó en el artículo de pyLint:

docker run  -v "$PWD:/app" -ti prueba-python  python -m cProfile -s cumtime raizcuadrada.py


A continuación se muestra una figura de la ejecución del comando:





Para más información pueden revisar la documentación oficial de python, un artículo en inglés sobre cProfile y una guía de análisis de rendimiento para python.

Instalar gitlab-runner de gitlab-ci por medio de Docker

En un artículo anterior se explicó como instalar gitlab-ce por medio de Docker (enlace).


El problema es que al gitlab le falta configurar lo de Integración Continua (CI), para ello es necesario instalar gitlab-runner (en el mismo equipo, en otro equipo o como un contenedor aparte).


La descripción sobre las características de gitlab-ci la pueden ver en el siguiente enlace.


La guía para instalar gitlab-runner lo pueden revisar en el siguiente enlace.

Para el caso de docker se puede ver la documentación siguiente.


Los artículos anteriores sobre Docker son:
  1. Instalar Docker en Debian Jessie
  2. Uso de Docker en Debian Jessie (parte 1)
  3. Uso de Docker en Debian Jessie (parte 2)
  4. Crear una imagen Docker a partir de un archivo Dockerfile
  5. Iniciando Django usando Docker
  6. Instalar Gitlab por medio de Docker
  7. Ejecutando microservicios con docker usando docker-compose
  8. Docker en Docker (DinD)
  9. Iniciando Django con docker usando docker-compose con postgresql como microservicio.
  10. Importar un contenedor Docker en Python.
  11. Compartir imagenes Docker por medio de archivos tar.
  12. Crear un registro de imagenes Docker privado.
  13. Usar Anaconda desde un contenedor Docker.
  14. Crear un entorno de Integración y Despligue continue con Docker para node.js.
  15. Usar Jupyter Notebook desde un contenedor Docker.
  16. Ejecutar una prueba de doctest con un contenedor Docker.
  17. Ejecutar una prueba de unittest en Python con un contenedor Docker.
  18. Montar una Plataforma como servicio (PaaS) con Dokku (docker).
  19. Uso de docker-machine.
  20. Proveer un cluster con docker swarm y docker-machine.
  21. Instalar Jenkins por medio de Docker y crear una imagen Docker de Jenkins
  22. Automatizar la construcción de imágenes Docker con github.
  23. Crear una imagen Docker para MongoDB3.
  24. Crear un contenedor Docker como entorno de desarrollo para Sails.js.
  25. Correr aplicaciones de escritorio desde un contenedor Docker.
  26. Usar dockerui para la gestión de imágenes y contenedores de Docker
  27. Crear una imagen Docker de RethinkDB
  28. Analizar código python con pylint desde Docker
Lo primero que se tiene que hacer es bajar la imagen de Docker para gitlab-runner:

docker pull gitlab/gitlab-runner

Luego se inicia el servicio de registro de gitlab-runner:

docker run -d --name gitlab-runner --restart always -v /srv/gitlab-runner/config:/etc/gitlab-runner -v /var/run/docker.sock:/var/run/docker.sock gitlab/gitlab-runner

De esta forma el gitlab-runner usará el docker que se encuentra en la máquina anfitrión, se tiene acceso a la configuración de gitlab-runner desde la máquina anfitrión.

Al ejecutar un docker ps se tiene lo siguiente:

docker ps 
CONTAINER ID        IMAGE                     COMMAND                  CREATED             STATUS              PORTS                                                            NAMES
13ffb573fadf        gitlab/gitlab-runner      "/entrypoint run --us"   3 hours ago         Up 3 hours                                                                           gitlab-runner
b483b38fe29e        gitlab/gitlab-ce:latest   "/assets/wrapper"        12 days ago         Up 4 hours          0.0.0.0:22->22/tcp, 0.0.0.0:443->443/tcp, 0.0.0.0:9080->80/tcp   gitlab1

Como se nota ya se tienen activo gitlab-ce y gitlab-runner.

Para registrar un proyecto se ejecuta en la máquina el siguiente comando:

docker exec -ti  13ffb573fadf  gitlab-runner register 

Lo que viene a continuación es registrar un proyecto que se encuentre en gitlab. En este caso se va a crear un proyecto en gitlab-ce y se va a la configuración del mismo, ahí se selecciona la parte de runners:

Se tiene el proyecto prueba-nodejs:


Los datos importantes son:
URL:http://192.168.0.60:9080/ci
TOKEN:6kN_Uo_j2YitsJkh7q94

A continuación se ejecuta el register:
docker exec -ti  13ffb573fadf  gitlab-runner register 

Y se pasa los datos que pide (la siguiente figura muestra la configuración del registro del proyecto):


Se le paso el url, el toke, luego pregunta la descripción del proyecto en este caso prueba-nodejs, luego unas etiquetas del mismo, se va a usar docker y por último la imagen base de Docker que se va  ausar.

Para terminar se mustra una imagen de la configuración del runner que indica que el runner y gitlab se encuentran conectados:

Y la información de esa conexión:


En próximo artículo se explicará como correr una prueba de CI. 

12 jun. 2016

Analizar código python con pylint desde Docker

Hace un tiempo escribí un artículo sobre analizar código python con pylint.


En este caso se tomará el artículo de pruebas unitarias con Docker y el de pylint para mostrar como se ejecuta el análisis de código python con Docker.


Los artículos anteriores sobre Docker son:
  1. Instalar Docker en Debian Jessie
  2. Uso de Docker en Debian Jessie (parte 1)
  3. Uso de Docker en Debian Jessie (parte 2)
  4. Crear una imagen Docker a partir de un archivo Dockerfile
  5. Iniciando Django usando Docker
  6. Instalar Gitlab por medio de Docker
  7. Ejecutando microservicios con docker usando docker-compose
  8. Docker en Docker (DinD)
  9. Iniciando Django con docker usando docker-compose con postgresql como microservicio.
  10. Importar un contenedor Docker en Python.
  11. Compartir imagenes Docker por medio de archivos tar.
  12. Crear un registro de imagenes Docker privado.
  13. Usar Anaconda desde un contenedor Docker.
  14. Crear un entorno de Integración y Despligue continue con Docker para node.js.
  15. Usar Jupyter Notebook desde un contenedor Docker.
  16. Ejecutar una prueba de doctest con un contenedor Docker.
  17. Ejecutar una prueba de unittest en Python con un contenedor Docker.
  18. Montar una Plataforma como servicio (PaaS) con Dokku (docker).
  19. Uso de docker-machine.
  20. Proveer un cluster con docker swarm y docker-machine.
  21. Instalar Jenkins por medio de Docker y crear una imagen Docker de Jenkins
  22. Automatizar la construcción de imágenes Docker con github.
  23. Crear una imagen Docker para MongoDB3.
  24. Crear un contenedor Docker como entorno de desarrollo para Sails.js.
  25. Correr aplicaciones de escritorio desde un contenedor Docker.
  26. Usar dockerui para la gestión de imágenes y contenedores de Docker
  27. Crear una imagen Docker de RethinkDB

El archivo Dockerfile cambió un poco con respecto al usado con las pruebas unitarias, ahora se usará como base a Debian, se instalará pylint por medio de apt-get y lo demás queda igual que en el artículo de pruebas unitarias. 

A continuación el archivo Dockerfile:

FROM debian
MAINTAINER Ernesto Crespo

RUN apt-get update 
RUN apt-get install -y pylint
RUN apt-get clean 

WORKDIR /app
COPY . /app


Los archivos que se usarán son los mismos utilizados en el de pruebas unitarias que se encuentra en el repositorio de github.

raizcuadrada
├── Dockerfile
├── LICENSE
├── raizcuadrada.py
├── raizcuadrada_test.py
└── README.md


El módulo raizcuadrada.py tiene lo siguiente:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Se importa el módulo math para calcular la raiz cuadrada.
"""
import math
#Función raiz cuadrada.
def Raiz(a):
    """Si a es mayor o igual a cero se calcula la raiz cuadrada"""
    if a >= 0:
        return math.sqrt(a)
    #Si es menor a cero se genera una excepción donde se informa que a debe ser mayor o igual a cero.
    else:
        raise ValueError("a debe ser >= 0")
if __name__ == '__main__':
    #Se importa el módulo doctest
    import doctest
    #Se realiza la prueba al archivo raizcuadra.txt
    doctest.testfile("raizcuadrada.txt")
La construcción de la imagen Docker se hace con el siguiente comando:

docker build -t prueba-python .

Para ejecutar el análisis desde docker se ejecuta:

docker run  -v "$PWD:/app" -ti prueba-python  pylint raizcuadrada.py

Y el resultado es el siguiente:


docker run  -v "$PWD:/app" -ti prueba-python  pylint raizcuadrada.py
No config file found, using default configuration
************* Module raizcuadrada
C: 16, 0: Line too long (101/80) (line-too-long)
C: 12, 0: Invalid function name "Raiz" (invalid-name)
C: 12, 0: Invalid argument name "a" (invalid-name)
Report
======
9 statements analysed.
Messages by category
--------------------
+-----------+-------+---------+-----------+
|type       |number |previous |difference |
+===========+=======+=========+===========+
|convention |3      |NC       |NC         |
+-----------+-------+---------+-----------+
|refactor   |0      |NC       |NC         |
+-----------+-------+---------+-----------+
|warning    |0      |NC       |NC         |
+-----------+-------+---------+-----------+
|error      |0      |NC       |NC         |
+-----------+-------+---------+-----------+
Messages
--------
+--------------+------------+
|message id    |occurrences |
+==============+============+
|invalid-name  |2           |
+--------------+------------+
|line-too-long |1           |
+--------------+------------+
Global evaluation
-----------------
Your code has been rated at 6.67/10
Raw metrics
-----------
+----------+-------+------+---------+-----------+
|type      |number |%     |previous |difference |
+==========+=======+======+=========+===========+
|code      |9      |36.00 |NC       |NC         |
+----------+-------+------+---------+-----------+
|docstring |4      |16.00 |NC       |NC         |
+----------+-------+------+---------+-----------+
|comment   |3      |12.00 |NC       |NC         |
+----------+-------+------+---------+-----------+
|empty     |9      |36.00 |NC       |NC         |
+----------+-------+------+---------+-----------+
Statistics by type
------------------
+---------+-------+-----------+-----------+------------+---------+
|type     |number |old number |difference |%documented |%badname |
+=========+=======+===========+===========+============+=========+
|module   |1      |NC         |NC         |100.00      |0.00     |
+---------+-------+-----------+-----------+------------+---------+
|class    |0      |NC         |NC         |0           |0        |
+---------+-------+-----------+-----------+------------+---------+
|method   |0      |NC         |NC         |0           |0        |
+---------+-------+-----------+-----------+------------+---------+
|function |1      |NC         |NC         |100.00      |100.00   |
+---------+-------+-----------+-----------+------------+---------+
Duplication
-----------
+-------------------------+------+---------+-----------+
|                         |now   |previous |difference |
+=========================+======+=========+===========+
|nb duplicated lines      |0     |NC       |NC         |
+-------------------------+------+---------+-----------+
|percent duplicated lines |0.000 |NC       |NC         |
+-------------------------+------+---------+-----------


De esta forma se puede ejecutar el análisis del código python con pylint usando Docker.


10 jun. 2016

Crear una imagen Docker de RethinkDB


RethinkDB es una base de datos NoSQL, opensource, es una base de datos que almacena documentos en formato JSON, facilita la inserción, actualización y busqueda en tiempo real (más info en el sitio de rethinkDB y en wikipedia).

La idea es construir una imagen de Docker por medio de un archivo Dockerfile, tomando como base Debian Jessie. Aunque se puede usar directamente la imagen de RethinkDB que se encuentra en el hub de docker.



Los artículos anteriores sobre Docker son:
  1. Instalar Docker en Debian Jessie
  2. Uso de Docker en Debian Jessie (parte 1)
  3. Uso de Docker en Debian Jessie (parte 2)
  4. Crear una imagen Docker a partir de un archivo Dockerfile
  5. Iniciando Django usando Docker
  6. Instalar Gitlab por medio de Docker
  7. Ejecutando microservicios con docker usando docker-compose
  8. Docker en Docker (DinD)
  9. Iniciando Django con docker usando docker-compose con postgresql como microservicio.
  10. Importar un contenedor Docker en Python.
  11. Compartir imagenes Docker por medio de archivos tar.
  12. Crear un registro de imagenes Docker privado.
  13. Usar Anaconda desde un contenedor Docker.
  14. Crear un entorno de Integración y Despligue continue con Docker para node.js.
  15. Usar Jupyter Notebook desde un contenedor Docker.
  16. Ejecutar una prueba de doctest con un contenedor Docker.
  17. Ejecutar una prueba de unittest en Python con un contenedor Docker.
  18. Montar una Plataforma como servicio (PaaS) con Dokku (docker).
  19. Uso de docker-machine.
  20. Proveer un cluster con docker swarm y docker-machine.
  21. Instalar Jenkins por medio de Docker y crear una imagen Docker de Jenkins
  22. Automatizar la construcción de imágenes Docker con github.
  23. Crear una imagen Docker para MongoDB3.
  24. Crear un contenedor Docker como entorno de desarrollo para Sails.js.
  25. Correr aplicaciones de escritorio desde un contenedor Docker.
  26. Usar dockerui para la gestión de imágenes y contenedores de Docker

El archivo Dockerfile toma parte del archivo oficial del sitio de RethinkDB, la idea es crear la imagen a partir de Debian Jessie (el dockerfile lo pueden ver en el siguiente enlace). 

El archivo Dockerfile es el siguiente:

#Base de Debian Jessie
FROM debian
#Mantenedor
MAINTAINER Ernesto Crespo <ecrespo@gmail.com>


# instalar RethinkDB
RUN apt-get update
RUN apt-get install -y software-properties-common
RUN apt-get install -y wget 
RUN sh -c 'echo "deb http://download.rethinkdb.com/apt `lsb_release -cs` main" | tee /etc/apt/sources.list.d/rethinkdb.list'
RUN sh -c 'wget -qO- https://download.rethinkdb.com/apt/pubkey.gpg | apt-key add -'
RUN apt-get update
RUN apt-get install -y rethinkdb

#Se define el volumen donde se almacena los datos
VOLUME ["/data"]

#Se define el directorio de trabajo
WORKDIR /data

#Se ejecuta rethinkdb asociando todas las interfaces existentes en el contenedor
CMD ["rethinkdb", "--bind", "all"]

#   proceso, cluster webui
EXPOSE 28015 29015 8080


Para construir la imagen se ejecuta:
docker build -t debian-rethinkdb . 

Y para correr el contenedor (se asocia el volumen /data al directorio donde se ejecuta el contenedor):
docker run --name some-rethink -v "$PWD:/data" -d debian-rethinkdb

Para ver la interfaz administrativa vía web de rethingDB se ejecuta (caso chromium):
chromium "http://$(docker inspect --format  '{{ .NetworkSettings.IPAddress }}' some-rethink):8080"

A continuación se muestra una captura de pantalla de la aplicación web:


AddThis