viernes, 20 de mayo de 2016

De como publicamos con pyramid una aplicación python

Todo el trabajo de ahora en adelante será el de usar la clase Usuarios como el core de nuestra aplicación, mientras que pyramid se encarga de publicarla webmente.

Básicamente, lo que se necesita es configurar las rutas en ./ambiente/aplicacion/aplicacion/__init__.py, mediante config.add_route()
    
    # Cuando request_method se encuentra acá, es devuelto un error como         
    # "The resource could not be found."                                        
    # Así que es como mejor configurar desde acá a request_method
    config.add_route('ficheros_listado', '/ficheros', request_method='GET')
Y luego escribir el controlador (Que acá se llaman vistas) para dicha ruta.
@view_config(route_name='ficheros_listado', renderer='json')                    
def ficheros_listado(request):                                                  
    """Cuando request_method se configura acà, el mensaje es diferente porque   
    la operación alcanzada es diferente                                         
        The resource could not be found.

predicate mismatch for view get_listar_ficheros (request_method = GET,HEAD)
    Por tanto lo mejor es configurarlo allá en __init__                         
    """                                                                         
    ficheros = Usuarios()                                                       
    listado = ficheros.listado()                                                
    return {'respuesta': listado}
Para no alargar demasiado, __init__.py queda de la siguiente forma:
# coding: utf-8                                                                 
from pyramid.config import Configurator                                         
                                                                                
                                                                                
def main(global_config, **settings):                                            
    """ This function returns a Pyramid WSGI application.                       
    """                                                                         
    config = Configurator(settings=settings)                                    
    # Cuando request_method se encuentra acá, es devuelto un error como         
    # "The resource could not be found."                                        
    # Así que es como mejor configurar desde acá a request_method               
    config.add_route('ficheros_listado', '/ficheros', request_method='GET')     
    config.add_route('ficheros_detalle', '/ficheros/{usuario}', request_method='GET')
    config.add_route('ficheros_creacion', '/ficheros', request_method='POST')   
    config.add_route('ficheros_modificacion', '/ficheros/{usuario}', request_method='PUT')
    config.add_route('ficheros_borrado', '/ficheros/{usuario}', request_method='DELETE')
    config.scan()                                                               
    return config.make_wsgi_app()
Y el fichero ./ambiente/aplicacion/aplicacion/views/actividades.py con las vistas (Que en realidad son controladores), queda de la siguiente forma:
# coding: utf-8
from pyramid.view import view_config
from ..fichero_app.ficheros import Usuarios
from pyramid import httpexceptions as exception

@view_config(route_name='ficheros_listado', renderer='json')
def ficheros_listado(request):
    """Cuando request_method se configura acà, el mensaje es diferente porque 
    la operación alcanzada es diferente
        The resource could not be found.


     predicate mismatch for view get_listar_ficheros (request_method = GET,HEAD)
    Por tanto lo mejor es configurarlo allá en __init__
    """
    ficheros = Usuarios()
    listado = ficheros.listado()
    return {'respuesta': listado}

@view_config(route_name='ficheros_detalle', renderer='json')
def ficheros_detalle(request):
    usuario = request.matchdict['usuario']
    ficheros = Usuarios()
    detalle = ficheros.detalle(usuario)
    return {'respuesta': detalle}

@view_config(route_name='ficheros_creacion', renderer='json')
def ficheros_creacion(request):
    try:
        usuario = request.json_body['usuario']
        data = request.json_body['data']
    except Exception as e:
        return exception.HTTPBadRequest()
    ficheros = Usuarios()
    creacion = ficheros.creacion(usuario, data)
    return {'respuesta': creacion}

@view_config(route_name='ficheros_modificacion', renderer='json')
def ficheros_modificacion(request):
    usuario = request.matchdict['usuario']
    try:
        data = request.json_body['data']
    except Exception as e:
        return exception.HTTPBadRequest()
    ficheros = Usuarios()
    modificacion = ficheros.modificacion(usuario, data)
    return {'respuesta': modificacion}

@view_config(route_name='ficheros_borrado', renderer='json')
def ficheros_borrado(request):
    usuario = request.matchdict['usuario']
    ficheros = Usuarios()
    borrado = ficheros.borrado(usuario)
    return {'respuesta': borrado}
Eso es todo. Con lo anterior nuestra clase Usuarios ha sido publicada a la web

Para ver que esto es cierto corremos el servidor web integrado desde el directorio raíz de la aplicación en ./ambiente/aplicacion (Que queda bien para desarrollo, pero no es la solución definitiva cuando lo vayamos a tirar en producción)
pserve development.ini --reload
En este punto ya podemos probar la aplicación desde la web. Bien podría ser desde un navegador, pero no. Como la idea es que esto funcione como una API, no deberíamos ocuparnos de crear interfaz web alguna, algo que sería necesario para verificar muchas de las operaciones que hemos definido. Lo más sencillo en este caso es crear las peticiones HTTP desde consola mediante curl, herramienta que sencillamente cambia la vida en cuanto se le toma práctica.
  • Para verificar el listado de ficheros en la raíz de ficheros/ mediante GET, especificamos el verbo HTTP con la opción -X
$ curl -X GET http://localhost:6543/ficheros -w "\n" 
{"respuesta": ["alortiz", "kpenate", "opineda"]}
  • Verifica la obtención de los datos particulares de un usuario en ficheros/{usuario}
$ curl -X GET http://localhost:6543/ficheros/alortiz -w "\n"
{"respuesta": {"palabras": ["ambiente", "publico"], "nombre": "Alexander", "apellido": "Ort\u00edz"}}
  • Creamos un usuario mediante el POST de ficheros/. Atención a como añadimos la cabecera content-type con -H,  y el valor que le hemos configurado. Luego, la opción -d nos permite configurar datos casi en bruto. El dato que enviamos es precisamente una cadena de texto que representa un JSON válido
$ curl -i -X POST http://localhost:6543/ficheros -w "\n" -H "content-type: application/json; charset=UTF-8" -d '{"data": {"palabras": ["estruendo", "epilepsia"], "nombre": "Francisco", "apellido": "Cornejo"}, "usuario": "fcornejo"}' 
{"respuesta": {"palabras": ["estruendo", "epilepsia"], "nombre": "Francisco", "apellido": "Cornejo"}}

$ curl -X GET http://localhost:6543/ficheros/fcornejo -w "\n"
{"respuesta": {"palabras": ["estruendo", "epilepsia"], "nombre": "Francisco", "apellido": "Cornejo"}}
  • Ahora modificamos al usuario fcornejo antes creado mediante el verbo PUT
$ curl -X PUT http://localhost:6543/ficheros/fcornejo -H "content-type: application/json" -d '{"data": {"palabras": ["esfuerzo", "historia"], "nombre": "Francisco", "apellido": "Cornejo"}, "usuario": "fcornejo"}' -w "\n"
{"respuesta": {"palabras": ["esfuerzo", "historia"], "nombre": "Francisco", "apellido": "Cornejo"}}
 
$ curl -X GET http://localhost:6543/ficheros/fcornejo -w "\n"
{"respuesta": {"palabras": ["esfuerzo", "historia"], "nombre": "Francisco", "apellido": "Cornejo"}}
  • Y por ultimo borramos al usuario fcornejo con el verbo DELETE
$ curl -X GET http://localhost:6543/ficheros -w "\n"
{"respuesta": ["alortiz", "kpenate", "opineda", "fcornejo"]}

$ curl -X DELETE http://localhost:6543/ficheros/fcornejo -w "\n"
{"respuesta": "fcornejo"}

$ curl -X GET http://localhost:6543/ficheros -w "\n"            
{"respuesta": ["alortiz", "kpenate", "opineda"]}

No hay comentarios:

Publicar un comentario en la entrada

Otros apuntes interesantes

Otros apuntes interesantes