31 oct. 2016

Volviendo a lo básico, POO en Python (parte 4)

Los artículos anteriores sobre Programación Orientada a Objetos los pueden revisar en el enlace.

En este artículo se tocará el tema de la herencia, la encapsulación, el uso de getter, setter y deleter, el uso de método estático y y classmethod.

En el artículo de la parte 3 de POO se explica el uso de @property y @método.setter, falto explicar el deleter que sirve para borrar atributos del objeto.

El @staticmethod se usa cuando no se está usando el argumento self en un método.

El @classmethod define un método que se le pasa entre los argumentos a la clase (por convención se define como cls).

Se creará la clase Punto2D con los siguientes atributos y métodos:

  • Se define al punto como (x,y), la clase Punto2 tiene los atributos privados (estos atributos no se pueden acceder a ellos desde la instancia de la clase, por esa razón se tiene el getter y setter):
    • self.__x
    • self.__y
  • Método __init__ que le asigna los valores inciales a la instancia.
  • getter, setter y deleter de punto.
  • getter, setter y deleter de ValorX y ValorY.
  • Método mover: Asigna nuevo valor a punto.
  • Método reset: Asigna el valor (0,0) al punto. 
  • Método distanciaOtroPunto: Cálcula la distancia con otro punto.



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



#!/usr/bin/env python3

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



from math import sqrt







class Punto2D(object):

    """Representacion de un punto en 2 dimensiones"""

    cont_puntos = 1



    def __init__(self,punto=(0,0)):

        '''constructor del punto'''

        self.__x,self.__y = punto

        Punto2D.cont_puntos += 1



    @property

    def ValorX(self):

        '''Devuelve el valor de X'''

        return self.__x



    @ValorX.setter

    def ValorX(self,x):

        '''Se le asigna un valor  a x por medio de setter'''

        self.__x = x



    @property

    def ValorY(self):

        '''Devuelve el valor de y'''

        return self.__y



    @ValorY.setter

    def ValorY(self,y):

        '''Se le asigna un valor a y por medio del setter'''

        self.__y = y



    @property

    def punto(self):

        """el getter de punto, devuelve el punto"""

        return (self.__x,self.__y)



    @punto.setter

    def punto(self,punto):

        ''''el setter de punto'''

        self.__x,self.__y = punto



    @property

    def cantPuntos(self):

        '''Devuelve la cantidad de puntos creados'''

        return Empleado.cont_puntos



    @punto.deleter

    def punto(self):

        '''deleter de punto'''

        del self.__x

        del self.__y

        cont_puntos = 0



    def mover(self,x,y):

        '''mueve el punto a un nuevo punto'''

        self.__x, self.__y = x,y



    def reset(self):

        '''coloca en el origen al punto'''

        self.mover(0,0)



    def distanciaOtroPunto(self,oPunto):

        '''devuelve la distancia entre el punto original y un punto dado'''

        return sqrt((self.__x - oPunto.punto[0])**2 + (self.__y - oPunto.punto[1])**2 )



    @staticmethod

    def autor(autor):

        '''Se define el autor de la clase'''

        return "El autor de esta clase es: {}".format(autor)



    @classmethod

    def cantidadPuntos(cls,cantidad):

        '''Se cambia la cantidad de puntos'''

        cls.cont_puntos = cantidad



if __name__ == "__main__":

    #Se crea cordenada de la clase Punto2D donde se le pasa (4,6)

    cordenada = Punto2D((4,6))

    #Se muestra el valor del punto.

    print(cordenada.punto)

    #Se asigna por setter un nuevo valor

    cordenada.punto = (10,15)

    #Se muestra el nuevo valor de cordenada

    print(cordenada.punto)

    #Se calcula la distancia con respecto a otro punto.

    print(cordenada.distanciaOtroPunto(Punto2D((100,100))))

    #Se fija el punto en un valor (0,0)

    cordenada.reset()

    #Se muestra el nuevo valor de la cordenada.

    print (cordenada.punto)

    #Se muestra un mensaje pasando el autor de la clase.

    print (cordenada.autor("Ernesto"))

    #Muestra la cantidad de puntos que se han creado.

    print ('Cantidad de puntos : {0}'.format(cordenada.cont_puntos ))

    #Se modifica la cantidad de puntos a 1 por medio de setter.

    Punto2D.cantidadPuntos(1)

    #Se vuelve a mostrar la cantida de puntos.

    print ('Cantidad de puntos : {0}'.format(cordenada.cont_puntos ))

    #Se borra la instancia cordenada.

    del(cordenada)

    #Se intenta mostrar el punto pero va a devolver que no se puede

    try:

        print (cordenada.punto)

    except (NameError):

        print ("No existe el objeto cordenada")



Al ejecutar ej12.py se tiene lo siguiente:

python ej12.py
(4, 6)
(10, 15)
123.794184031
(0, 0)
El autor de esta clase es: Ernesto
Cantidad de puntos : 3
Cantidad de puntos : 1
No existe el objeto cordenada



Ahora se va a crear ej12_3d.py que tendrá la clase Punto3D que hereda de Punto2D.

La clase Punto3D tiene practicamente los mismos métodos, lo único distinto es que ahora maneja un punto con 3 dimensiones, para ello hereda del punto en 2 dimensiones X y Y y maneja Z. 

Así que se sobrecarga los métodos de Punto2D en Punto3D. Para poder acceder al objeto Punto2D se usa super. 

A continuación el código de ej12_3d.py:



#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#Se importa la clase Punto2D de ej12.py
from ej12 import Punto2D
#Se importa raiz cuadrada
from math import sqrt
class Punto3D(Punto2D):
    '''Se define la clase Punto3D'''
    def __init__(self,punto3d):
        '''Método init donde se le asigna x y y a Punto2D por medio de super'''
        super(Punto3D,self).__init__(punto3d[0:-1])
        self.__z = punto3d[-1]
    @property
    def ValorZ(self):
        '''devuelve el valor de z por medio de getter'''
        return self.__z
    @ValorZ.setter
    def ValorZ(self,z):
        '''Se asigna un valor a z por medio de setter'''
        self.__z = z
    @ValorZ.deleter
    def ValorZ(self):
        '''se borra el valor de z por medio de deleter'''
        del (self.__z)
    @property
    def punto(self):
        '''el getter de punto, devuelve el punto'''
        x,y = super(Punto3D,self).punto
        return (x,y,self.ValorZ)
    @punto.setter
    def punto(self,punto3d):
        '''Se le asigna un valor al punto por medio de setter'''
        super(Punto3D,self).mover(punto3d[0],punto3d[1])
        self.__z = punto3d[-1]
    @punto.deleter
    def punto(self):
        '''Se borra el punto por medio de deleter'''
        print ("Punto borrado")
        del Punto2D
        del self.__z
    def mover(self,x,y,z):
        '''Se asigna un nuevo valor al punto''''
        super(Punto3D,self).mover(x,y)
        self.__z = z
    def reset(self):
        '''Se fija el punto como (0,0,0)'''
        super(Punto3D,self).mover(0,0)
        self.__z = 0
    def distanciaOtroPunto(self,oPunto):
        '''devuelve la distancia entre el punto original y un punto dado'''
        x,y = super(Punto3D,self).punto
        z = self.__z
        return sqrt((x - oPunto.punto[0])**2 + (y - oPunto.punto[1])**2 + (z - oPunto.ValorZ) ** 2 )
if __name__ == '__main__':
    #Se crea la instancia Punto3D con el punto.
    punto3d = Punto3D((4,6,4))
    #Se muestra el valor del punto
    print(punto3d.punto)
    #Se asigna un nuevo valor a punto.
    punto3d.punto = (3,3,3)
    #Se muestra dicho valor
    print(punto3d.punto)
    #Se muestra los valores de x,y y z.
    print(punto3d.ValorX)
    print(punto3d.ValorY)
    print(punto3d.ValorZ)
    #Se asigna el valor (0,0,0)
    punto3d.reset()
    #Se muestra su valor.
    print(punto3d.punto)
    #Se calcula la distancia con otro punto.
    print(punto3d.distanciaOtroPunto(Punto3D((15,45,55))))
    #Se borra el punto3d.
    del(punto3d)
    #Se intenta mostrar el valor o devuelve que el objeto no existe.
    try:
        print (punto3d.punto)
    except (NameError):
        print ("No existe el objeto punto3d")



Al ejecutar ej12_3d.py se obtiene lo siguiente:

python ej12_3d.py
(4, 6, 4)
(3, 3, 3)
3
3
3
(0, 0, 0)
72.6291952317
No existe el objeto punto3d



En este artículo se muestra la encapsulación, la herencia y varios métodos.

Los códigos lo pueden encontrar en gitlab tanto para ej12.py como para ej12_3d.py.


12 oct. 2016

API Rest Ful con Flask y MongoDB (Flask-MongoAlchemy y Flask-restful)

 API Rest Ful con Flask y MongoDB (Flask-MongoAlchemy y Flask-restful)


En el artículo anterior se explicó como hacer el API Rest Ful usando HTTP con los métodos GET, POST, PUT y DELETE, sin usar una librería para el Rest Ful. 

En este artículo se usará la librería Flask-RestFul, su documentación la pueden revisar acá

Estructura de archivos y directorios del proyecto


La estructura de archivos y directorios sigue siendo la misma que en el artículo anterior:

tutorial-flask/
├── app
│   └── run.py
├── docker-compose.yml
├── Dockerfile
└── README.md



Archivo Dockerfile y docker-compose.yml


Al archivo Dockerfile se le agrega que se instale flask-restful, a continuación el archivo:



FROM python
WORKDIR /code/
RUN pip3 install --upgrade pip
RUN pip3 install  pymongo
RUN pip3 install Flask
RUN pip3 install Flask-PyMongo
RUN pip3 install Flask-MongoAlchemy
RUN pip3 install Flask-restful
EXPOSE 5000
ADD ./app/* /code/
COPY ./app/* /code/
CMD python run.py
El archivo docker-compose.yml si es el mismo del artículo anterior:

flask-rest1:
  build: .
  ports:
    - "5000:5000"
  volumes:
    - "./app/:/code"
  links:
    - mongo
mongo:
  image: mongo
  ports:
    - "27017:27017"
  volumes:
    - "/srv/data/db:/data/db:rw"



Código de la aplicación


Se usarán los mismos métodos HTTP del artículo anterior (GET,POST,PUT y DELETE), el url para las consultas será /empleados y la forma de pasar argumentos por el url es pasando el nombre del empleado /empleados/<string:nombre>  . 

Se crean dos clases:
  • EmpleadoList: Esta clase no se le pasa argumentos por URL, tiene dos métdos GET y POST:
    • GET: Permite listar los empleados que existen en la base de datos.
    • POST: Permite insertar un empleado a la base de datos pasando un json con los datos.
  • Empleado: que a los métodos se le pasa el nombre de un empleado. Se define los métodos GET, PUT y DELETE:
    • GET: Permite buscar un empleado pasando su nombre, se devuelve un json con sus datos.
    • PUT: Permite actualizar la información de un empleado, pasando su nombre y el json con los datos a modificar, devuelve un jso con todos los empleados.
    • DELETE: Permite borrar un empleado de la base de datos, se le pasa el nombre del empleado, devuelve un json con todos los empleados.


El código de app/run.py se muestra a continunación:



#!/usr/bin/env python
#Se importa Flask, reqest y jsonify
from flask import Flask, request,jsonify, Response
#Se importa MongoAlchemy
from flask_mongoalchemy import MongoAlchemy
#Se importa dumps
from bson.json_util import dumps
#rom flask_restful import Resource, Api
from flask_restful import reqparse, abort, Api, Resource
#Se instancia la clase de Flask, se configura el acceso
#a la base de datos mongodb a empleados
app = Flask(__name__)
app.config['MONGOALCHEMY_DATABASE'] = 'empleados'
app.config['MONGOALCHEMY_CONNECTION_STRING'] = 'mongodb://mongo:27017/empleados'
#Se instancia mongoalchemy pasando la app.
db = MongoAlchemy(app)
#Se asocia el API a la aplicacion
api = Api(app)
#Se crea la clase empleados la cual manejara los documentos.
class empleados(db.Document):
    nombre = db.StringField()
    sexo = db.StringField()
    edad = db.IntField()
    dni = db.IntField()
#Se define la funcion de pagina no encontrada.
@app.errorhandler(404)
def not_found(error=None):
    mensaje = {
            'status': 404,
            'message': 'Not Found: ' + request.url,
    }
    resp = Response(jsonify(mensaje),status=404,mimetype='application/json')
    return resp
#Clase EmpleadosList que permite listar los empleados o insertar un empledo.
#Se definen los metdos get y post
class EmpleadosList(Resource):
    #Se define el metodo get el cual devuelve un json con todos los empleados.
    def get(self):
        #Se realiza la busqueda y se devuelve el resultado, si existe un error de atributo (que el empleado no existe)
        #Se devuelve empleado no encontrado.
        try:
            consulta = empleados.query.all()
            resultado = []
            for i in consulta:
                resultado.append(i.wrap())
            resp =  Response(dumps(resultado),status=200,mimetype='application/json')
            resp.headers['Link'] = 'http://blog.crespo.org.ve'
            return resp
        except (AttributeError):
            return not_found
    #Se define el metodo post para agregar un empleado por medio de un json a la
    #base de datos mongoDB.
    def post(self):
        #args = parser.parse_args()
        #Se crea la instancia empleado de la clase empleados donde se
        #logra hacer la inserción de un empleado con el metodo save.
        nombre = str(request.json['nombre'])
        sexo = str(request.json['sexo'])
        edad = int(request.json['edad'])
        dni = int(request.json['dni'])
        empleado = empleados(nombre=nombre,sexo=sexo,edad=edad,dni=dni)
        empleado.save()
        #Se retorna que el usuario fue agregado.
        ###
        consulta = empleados.query.all()
        listado = []
        for i in consulta:
            listado.append(i.wrap())
        resp =  Response(dumps(listado),status=201,mimetype='application/json')
        resp.headers['Link'] = 'http://blog.crespo.org.ve'
        return resp
#Se crea la Clase Empleado que hereda de Resource
#Tiene los metodos get, put y delete
class Empleado(Resource):
    #Se define el metodo get, permite buscar un empleado por su nombre
    def get(self,nombre):
        #Se realiza la busqueda y se devuelve el resultado, si existe un error de atributo (que el empleado no existe)
        #Se devuelve empleado no encontrado.
        try:
            resultado = empleados.query.filter(empleados.nombre == nombre).first()
            return dumps({'nombre':resultado.nombre,'sexo':resultado.sexo,'edad':resultado.edad,'dni':resultado.dni}),200,{'Content-Type':'application/json'}
        except (AttributeError):
            return not_found
    #Se define el metodo put que permite actualizar la informacion de un empleado
    #pasando su nombre, los datos a modificar se pasan en un json.
    def put(self,nombre):
        #Se intenta buscar al empleado en la base de datos, si no esta devuelve error
        try:
            #Se consulta en la base de datos, donde devuelve el primer elemento encontrado
            resultado = empleados.query.filter(empleados.nombre == nombre).first()
            #Se toma los datos de un json y se guardan en sus variables, salvando luego
            #en la base de datos.
            resultado.sexo = str(request.json['sexo'])
            resultado.edad = int(request.json['edad'])
            resultado.dni = int(request.json['dni'])
            resultado.save()
            #Se realiza la consulta desplegando los empleados
            consulta = empleados.query.all()
            listado = []
            for i in consulta:
                listado.append(i.wrap())
            #Se devuelve la nueva lista de empleados en un json.
            resp =  Response(dumps(listado),status=201,mimetype='application/json')
            resp.headers['Link'] = 'http://blog.crespo.org.ve'
            return resp
        except (AttributeError):
            return not_found
    #Se define el metodo delete que permite borrar un empleado de la base de datos
    #pasando el nombre del empleado.
    def delete(self,nombre):
        #Se busca el empleado, si existe se borra de la base de datos y se devuelve
        #mensaje de empleado borrado, si no, se devuelve el mensaje de empleado no
        #encontrado.
        try:
            resultado = empleados.query.filter(empleados.nombre == nombre).first()
            resultado.remove()
            ###
            consulta = empleados.query.all()
            listado = []
            for i in consulta:
                listado.append(i.wrap())
            resp =  Response(dumps(listado),status=200,mimetype='application/json')
            resp.headers['Link'] = 'http://blog.crespo.org.ve'
            return resp
        except (AttributeError):
            return not_found
#Se define las rutas para los recursos con las clases asociadas:
#/empleado
#/empleado/<string:nombre>
api.add_resource(EmpleadosList,'/empleado')
api.add_resource(Empleado,'/empleado/<string:nombre>')
if __name__ == "__main__":
    #Se corre la aplicacion en modo debug
    app.run(host="0.0.0.0",debug=True)


Construcción de la imagen y ejecución del contenedor


Construcción de la imagen Docker:

docker-compose build


Ejecución del contenedor Docker:

docker-compose up


Prueba del API Rest Ful

Se usará postman para consultar al API.

Listar todos los empleados

Se abre postman en el url http://localhost:5000/empleado con método GET, a continuación se muestra una captura de pantalla:


El JSON que se devuelve es el siguiente:

[{"edad": 29, "sexo": "Femenino", "nombre": "Jane Doe", "dni": 8, "_id": {"$oid": "57ebbce45fd2bbeffc51330b"}}, {"edad": 39, "sexo": "Masculino", "nombre": "John Doe", "dni": 7, "_id": {"$oid": "57ebbd195fd2bbeffc51330c"}}, {"edad": 55, "sexo": "Masculino", "nombre": "Pedro Perez", "dni": 6, "_id": {"$oid": "57ebbd505fd2bbeffc51330d"}}, {"edad": 65, "sexo": "Femenino", "nombre": "Petra", "dni": 5, "_id": {"$oid": "57ebbd6b5fd2bbeffc51330e"}}, {"edad": 18, "sexo": "Masculino", "nombre": "Luis Gonzalez", "dni": 4, "_id": {"$oid": "57ebc34d5fd2bbeffc51330f"}}, {"edad": 34, "sexo": "Femenino", "nombre": "Luissana", "dni": 2, "_id": {"$oid": "57ebc3935fd2bbeffc513311"}}, {"edad": 42, "sexo": "Masculino", "nombre": "Neg", "dni": 1, "_id": {"$oid": "57ebc4b85fd2bbeffc513312"}}, {"edad": 29, "sexo": "Femenino", "nombre": "Dayana", "dni": 1050, "_id": {"$oid": "57f64d7d557e3f00086651e8"}}]

Agregar un empleado


Se abre postman en el URL http://localhost:5000/empleado con método POST y se pasa el siguiente JSON:

{
"nombre": "Nadir",
"sexo": "Masculino",
"edad": 45,
"dni": 11059
}



A continuación se muestra la captura de pantalla de la colocación de los datos:


Al ejecutar la acción se tiene el siguiente resueltado (como lo muestra la siguiente captura de pantalla):



El JSON que se devuelve es el siguiente:

[{"edad": 29, "sexo": "Femenino", "nombre": "Jane Doe", "dni": 8, "_id": {"$oid": "57ebbce45fd2bbeffc51330b"}}, {"edad": 39, "sexo": "Masculino", "nombre": "John Doe", "dni": 7, "_id": {"$oid": "57ebbd195fd2bbeffc51330c"}}, {"edad": 55, "sexo": "Masculino", "nombre": "Pedro Perez", "dni": 6, "_id": {"$oid": "57ebbd505fd2bbeffc51330d"}}, {"edad": 65, "sexo": "Femenino", "nombre": "Petra", "dni": 5, "_id": {"$oid": "57ebbd6b5fd2bbeffc51330e"}}, {"edad": 18, "sexo": "Masculino", "nombre": "Luis Gonzalez", "dni": 4, "_id": {"$oid": "57ebc34d5fd2bbeffc51330f"}}, {"edad": 34, "sexo": "Femenino", "nombre": "Luissana", "dni": 2, "_id": {"$oid": "57ebc3935fd2bbeffc513311"}}, {"edad": 42, "sexo": "Masculino", "nombre": "Neg", "dni": 1, "_id": {"$oid": "57ebc4b85fd2bbeffc513312"}}, {"edad": 29, "sexo": "Femenino", "nombre": "Dayana", "dni": 1050, "_id": {"$oid": "57f64d7d557e3f00086651e8"}}, {"edad": 45, "sexo": "Masculino", "nombre": "Nadir", "dni": 11059, "_id": {"$oid": "57fe2800d76747000b2ef40f"}}]


Buscar un empleado

Para buscar un empleado se pasa el siguiente URL http://localhost:5000/empleado/Nadir con método GET al postman, a continuación se muestra una captura de pantalla del resultado:


El JSON que devuelve es el siguiente:

"{\"edad\": 45, \"sexo\": \"Masculino\", \"nombre\": \"Nadir\", \"dni\": 11059}"


Actualizar empleado


Para actualizar al empleado Nadir se pasará el siguiente url a postman http://localhost:5000/empleado/Nadir con método PUT, y se pasará el siguiente json:

{
"sexo": "Masculino",
"edad": 35,
"dni": 11059
}

La captura de pantalla muestra los datos que se cargaron a postman:







Al ejecutar la acción se tiene la siguiente captura de pantalla:



El JSON que devuelve es el siguiente:

[{"edad": 29, "sexo": "Femenino", "nombre": "Jane Doe", "dni": 8, "_id": {"$oid": "57ebbce45fd2bbeffc51330b"}}, {"edad": 39, "sexo": "Masculino", "nombre": "John Doe", "dni": 7, "_id": {"$oid": "57ebbd195fd2bbeffc51330c"}}, {"edad": 55, "sexo": "Masculino", "nombre": "Pedro Perez", "dni": 6, "_id": {"$oid": "57ebbd505fd2bbeffc51330d"}}, {"edad": 65, "sexo": "Femenino", "nombre": "Petra", "dni": 5, "_id": {"$oid": "57ebbd6b5fd2bbeffc51330e"}}, {"edad": 18, "sexo": "Masculino", "nombre": "Luis Gonzalez", "dni": 4, "_id": {"$oid": "57ebc34d5fd2bbeffc51330f"}}, {"edad": 34, "sexo": "Femenino", "nombre": "Luissana", "dni": 2, "_id": {"$oid": "57ebc3935fd2bbeffc513311"}}, {"edad": 42, "sexo": "Masculino", "nombre": "Neg", "dni": 1, "_id": {"$oid": "57ebc4b85fd2bbeffc513312"}}, {"edad": 29, "sexo": "Femenino", "nombre": "Dayana", "dni": 1050, "_id": {"$oid": "57f64d7d557e3f00086651e8"}}, {"edad": 35, "sexo": "Masculino", "nombre": "Nadir", "dni": 11059, "_id": {"$oid": "57fe2800d76747000b2ef40f"}}]

Como se puede notar los datos del empleado Nadir en lo que respecta a su edad ha cambiado.

Borrar empleado

Para terminar se borrará el empleado Nadir de la base de datos, se pasa el url http://localhost/empleado/Nadir con método DELETE, a continuación se muestra el resultado en el postman:


El JSON que devuelve es el siguiente:

[{"edad": 29, "sexo": "Femenino", "nombre": "Jane Doe", "dni": 8, "_id": {"$oid": "57ebbce45fd2bbeffc51330b"}}, {"edad": 39, "sexo": "Masculino", "nombre": "John Doe", "dni": 7, "_id": {"$oid": "57ebbd195fd2bbeffc51330c"}}, {"edad": 55, "sexo": "Masculino", "nombre": "Pedro Perez", "dni": 6, "_id": {"$oid": "57ebbd505fd2bbeffc51330d"}}, {"edad": 65, "sexo": "Femenino", "nombre": "Petra", "dni": 5, "_id": {"$oid": "57ebbd6b5fd2bbeffc51330e"}}, {"edad": 18, "sexo": "Masculino", "nombre": "Luis Gonzalez", "dni": 4, "_id": {"$oid": "57ebc34d5fd2bbeffc51330f"}}, {"edad": 34, "sexo": "Femenino", "nombre": "Luissana", "dni": 2, "_id": {"$oid": "57ebc3935fd2bbeffc513311"}}, {"edad": 42, "sexo": "Masculino", "nombre": "Neg", "dni": 1, "_id": {"$oid": "57ebc4b85fd2bbeffc513312"}}, {"edad": 29, "sexo": "Femenino", "nombre": "Dayana", "dni": 1050, "_id": {"$oid": "57f64d7d557e3f00086651e8"}}]

Como se puede ver el empleado Nadir ya no existe en la base de datos.


Para terminar se muestra la captura de pantalla del contenedor ejecutandose:



Se mantiene resaltado la salida de la ejecución de Flask ( a continuación se muestra el texto):

flask-rest1_1 | 172.17.0.1 - - [12/Oct/2016 12:02:56] "GET /empleado HTTP/1.1" 200 -
mongo_1       | 2016-10-12T12:09:37.175+0000 I COMMAND  [conn2] update empleados.empleados query: { _id: ObjectId('57fe2800d76747000b2ef40f') } update: { _id: ObjectId('57fe2800d76747000b2ef40f'), edad: 45, sexo: "Masculino", nombre: "Nadir", dni: 11059 } keysExamined:0 docsExamined:0 nMatched:1 nModified:1 upsert:1 keyUpdates:0 writeConflicts:0 numYields:1 locks:{ Global: { acquireCount: { r: 2, w: 2 } }, Database: { acquireCount: { w: 2 } }, Collection: { acquireCount: { w: 2 } } } 326ms
flask-rest1_1 | 172.17.0.1 - - [12/Oct/2016 12:09:37] "POST /empleado HTTP/1.1" 201 -
flask-rest1_1 | 172.17.0.1 - - [12/Oct/2016 12:12:40] "GET /empleado/Nadir HTTP/1.1" 200 -
flask-rest1_1 | 172.17.0.1 - - [12/Oct/2016 12:18:23] "POST /empleado/Nadir HTTP/1.1" 405 -
mongo_1       | 2016-10-12T12:20:00.777+0000 I COMMAND  [conn2] update empleados.empleados query: { _id: ObjectId('57fe2800d76747000b2ef40f') } update: { _id: ObjectId('57fe2800d76747000b2ef40f'), edad: 35, sexo: "Masculino", nombre: "Nadir", dni: 11059 } keysExamined:1 docsExamined:1 nMatched:1 nModified:1 keyUpdates:0 writeConflicts:0 numYields:2 locks:{ Global: { acquireCount: { r: 3, w: 3 } }, Database: { acquireCount: { w: 3 } }, Collection: { acquireCount: { w: 3 } } } 124ms
flask-rest1_1 | 172.17.0.1 - - [12/Oct/2016 12:20:00] "PUT /empleado/Nadir HTTP/1.1" 201 -
flask-rest1_1 | 172.17.0.1 - - [12/Oct/2016 12:23:19] "DELETE /empleado/Nadir HTTP/1.1" 200 -



Con esto se ha mejorado la forma de como crear un API Rest, en este caso usando flask-restful. 

El repositorio del proyecto se encuentra en el repositorio gitlab tutorial-flask en la rama mongo-flask-restful.


AddThis