martes, 18 de junio de 2019

Python Flask CRUD REST APP

Una Aplicacion CRUD en python con libreria Flask para servicios REST

github
https://github.com/jalbertomr/Python-Flask-CRUD-REST-APP.git

Preparamos el ambiente de trabajo, se incluye virtualenv para ejecución de python

bext@bext-VPCF13WFX:~$ mkdir workspace
bext@bext-VPCF13WFX:~$ cd workspacebext@bext-VPCF13WFX:~/workspace$ mkdir flask-crud-rest-app
bext@bext-VPCF13WFX:~/workspace$ cd flask-crud-rest-app
bext@bext-VPCF13WFX:~/workspace/flask-crud-rest-app$ ls
bext@bext-VPCF13WFX:~/workspace/flask-crud-rest-app$ virtualenv -p /usr/bin/python3.4 venv

Command 'virtualenv' not found, but can be installed with:

sudo apt install virtualenv

Se instala virtualenv

bext@bext-VPCF13WFX:~/workspace/flask-crud-rest-app$ sudo apt install virtualenv
[sudo] password for bext:
Reading package lists... Done
Building dependency tree      
Reading state information... Done
The following additional packages will be installed:
  python-pip-whl python3-distutils python3-lib2to3 python3-virtualenv
The following NEW packages will be installed:
  python-pip-whl python3-distutils python3-lib2to3 python3-virtualenv
  virtualenv
0 upgraded, 5 newly installed, 0 to remove and 12 not upgraded.
Need to get 1 918 kB of archives.
After this operation, 4 144 kB of additional disk space will be used.
Do you want to continue? [Y/n] Y
Get:1 http://mx.archive.ubuntu.com/ubuntu bionic-updates/universe amd64 python-pip-whl all 9.0.1-2.3~ubuntu1.18.04.1 [1 653 kB]
Get:2 http://mx.archive.ubuntu.com/ubuntu bionic-updates/main amd64 python3-lib2to3 all 3.6.8-1~18.04 [76.5 kB]
Get:3 http://mx.archive.ubuntu.com/ubuntu bionic-updates/main amd64 python3-distutils all 3.6.8-1~18.04 [141 kB]
Get:4 http://mx.archive.ubuntu.com/ubuntu bionic/universe amd64 python3-virtualenv all 15.1.0+ds-1.1 [43.4 kB]
Get:5 http://mx.archive.ubuntu.com/ubuntu bionic/universe amd64 virtualenv all 15.1.0+ds-1.1 [4 476 B]
Fetched 1 918 kB in 2s (791 kB/s)         
Selecting previously unselected package python-pip-whl.
(Reading database ... 173804 files and directories currently installed.)
Preparing to unpack .../python-pip-whl_9.0.1-2.3~ubuntu1.18.04.1_all.deb ...
Unpacking python-pip-whl (9.0.1-2.3~ubuntu1.18.04.1) ...
Selecting previously unselected package python3-lib2to3.
Preparing to unpack .../python3-lib2to3_3.6.8-1~18.04_all.deb ...
Unpacking python3-lib2to3 (3.6.8-1~18.04) ...
Selecting previously unselected package python3-distutils.
Preparing to unpack .../python3-distutils_3.6.8-1~18.04_all.deb ...
Unpacking python3-distutils (3.6.8-1~18.04) ...
Selecting previously unselected package python3-virtualenv.
Preparing to unpack .../python3-virtualenv_15.1.0+ds-1.1_all.deb ...
Unpacking python3-virtualenv (15.1.0+ds-1.1) ...
Selecting previously unselected package virtualenv.
Preparing to unpack .../virtualenv_15.1.0+ds-1.1_all.deb ...
Unpacking virtualenv (15.1.0+ds-1.1) ...
Setting up python-pip-whl (9.0.1-2.3~ubuntu1.18.04.1) ...
Processing triggers for man-db (2.8.3-2ubuntu0.1) ...
Setting up python3-lib2to3 (3.6.8-1~18.04) ...
Setting up python3-distutils (3.6.8-1~18.04) ...
Setting up python3-virtualenv (15.1.0+ds-1.1) ...
Setting up virtualenv (15.1.0+ds-1.1) ...
bext@bext-VPCF13WFX:~/workspace/flask-crud-rest-app$ 

bext@bext-VPCF13WFX:~/workspace/flask-crud-rest-app$ virtualenv -p /usr/bin/python3 venv
Already using interpreter /usr/bin/python3
Using base prefix '/usr'
New python executable in /home/bext/workspace/flask-crud-rest-app/venv/bin/python3
Also creating executable in /home/bext/workspace/flask-crud-rest-app/venv/bin/python
Installing setuptools, pkg_resources, pip, wheel...done.
bext@bext-VPCF13WFX:~/workspace/flask-crud-rest-app$ ls
venv

Activamos el ambiente virtual

bext@bext-VPCF13WFX:~/workspace/flask-crud-rest-app$ source venv/bin/activate
(venv) bext@bext-VPCF13WFX:~/workspace/flask-crud-rest-app$

Instalamos flask en el amibiente virutal con pip

(venv) bext@bext-VPCF13WFX:~/workspace/flask-crud-rest-app$ pip3 install flask
Collecting flask
  Downloading https://files.pythonhosted.org/packages/9a/74/670ae9737d14114753b8c8fdf2e8bd212a05d3b361ab15b44937dfd40985/Flask-1.0.3-py2.py3-none-any.whl (92kB)
     |████████████████████████████████| 92kB 321kB/s
Collecting Jinja2>=2.10 (from flask)
  Downloading https://files.pythonhosted.org/packages/1d/e7/fd8b501e7a6dfe492a433deb7b9d833d39ca74916fa8bc63dd1a4947a671/Jinja2-2.10.1-py2.py3-none-any.whl (124kB)
     |████████████████████████████████| 133kB 432kB/s
Collecting click>=5.1 (from flask)
  Downloading https://files.pythonhosted.org/packages/fa/37/45185cb5abbc30d7257104c434fe0b07e5a195a6847506c074527aa599ec/Click-7.0-py2.py3-none-any.whl (81kB)
     |████████████████████████████████| 81kB 949kB/s
Collecting Werkzeug>=0.14 (from flask)
  Downloading https://files.pythonhosted.org/packages/9f/57/92a497e38161ce40606c27a86759c6b92dd34fcdb33f64171ec559257c02/Werkzeug-0.15.4-py2.py3-none-any.whl (327kB)
     |████████████████████████████████| 327kB 1.4MB/s
Collecting itsdangerous>=0.24 (from flask)
  Downloading https://files.pythonhosted.org/packages/76/ae/44b03b253d6fade317f32c24d100b3b35c2239807046a4c953c7b89fa49e/itsdangerous-1.1.0-py2.py3-none-any.whl
Collecting MarkupSafe>=0.23 (from Jinja2>=2.10->flask)
  Downloading https://files.pythonhosted.org/packages/b2/5f/23e0023be6bb885d00ffbefad2942bc51a620328ee910f64abe5a8d18dd1/MarkupSafe-1.1.1-cp36-cp36m-manylinux1_x86_64.whl
Installing collected packages: MarkupSafe, Jinja2, click, Werkzeug, itsdangerous, flask
Successfully installed Jinja2-2.10.1 MarkupSafe-1.1.1 Werkzeug-0.15.4 click-7.0 flask-1.0.3 itsdangerous-1.1.0
(venv) bext@bext-VPCF13WFX:~/workspace/flask-crud-rest-app$

Codificamos una simple app.py y la ejecutamos


instalamos flask_restfull
#pip install flask_restfull

Se crean tres archivos que tendran el codigo para responder a peticiones REST

eston son: app.py, api/__init__.py, api/Task.py



app.py
from flask import Flask
import logging as logger

logger.basicConfig(level="DEBUG")
flaskAppInstance = Flask(__name__)

if __name__ == '__main__':
    logger.debug("Arrancando la aplicacion")
    from api import *
    flaskAppInstance.run(host="0.0.0.0", port=5000, debug=True, use_reloader=True)

api/__init__.py
from flask_restful import Api

from app import flaskAppInstance
from .Task import Task

restServer = Api(flaskAppInstance)

restServer.add_resource(Task, "/api/v1.0/task")

Task.py
from flask_restful import Resource
import logging as logger

class Task(Resource):

    def get(self):
        logger.debug("En get method")
        return {"message": "En get method"}, 200
    def post(self):
        logger.debug("EN post method")
        return {"message": "En post method"}, 200
    def put(self):
        logger.debug("En put method")
        return {"message": "En put method"}, 200
    def delete(self):
        logger.debug("En delete method")
        return {"message": "En delete method"}, 200

ejecutamos la aplicacion
#python app.py
DEBUG:root:Arrancando la aplicacion
 * Serving Flask app "app" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: on
INFO:werkzeug: * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
INFO:werkzeug: * Restarting with stat
DEBUG:root:Arrancando la aplicacion
WARNING:werkzeug: * Debugger is active!
INFO:werkzeug: * Debugger PIN: 243-904-832


Ejecutamos postman para probar el servicio REST

DEBUG:root:En get method
INFO:werkzeug:127.0.0.1 - - [18/Jun/2019 20:56:43] "GET /api/v1.0/task HTTP/1.1" 200 -



DEBUG:root:EN post method
INFO:werkzeug:127.0.0.1 - - [18/Jun/2019 20:57:59] "POST /api/v1.0/task HTTP/1.1" 200 -


Enviando Parametros al las peticiones RESP

Para enviar parametros debemos especificar el recurso y hacer los cambios respectivos en los archivos de codigo. en este caso agregando el archivo TaskById.py que tiene el codigo de manejo REST por parametros, notese que los 2 recursos con y sin parametros se especifican en __init__.py

__init__.py
from flask_restful import Api

from app import flaskAppInstance
from .Task import Task
from .TaskById import TaskById

restServer = Api(flaskAppInstance)

restServer.add_resource(Task, "/api/v1.0/task")
restServer.add_resource(TaskById, "/api/v1.0/task/Id/<string:taskId>")

TaskById.py
from flask_restful import Resource
import logging as logger


class TaskById(Resource):

    def get(self, taskId):
        logger.debug("En get method por task by id. taskId = {}".format(taskId))
        return {"message": "En get method por task by id. taskId = {}".format(taskId)}, 200
    def post(self, taskId):
        logger.debug("EN post method por task by id. taskId = {}".format(taskId))
        return {"message": "En post method por task by id. taskId = {}".format(taskId)}, 200
    def put(self, taskId):
        logger.debug("En put method por task by id. taskId = {}".format(taskId))
        return {"message": "En put method por task by id. taskId = {}".format(taskId)}, 200
    def delete(self, taskId):
        logger.debug("En delete method por task by id. taskId = {}".format(taskId))
        return {"message": "En delete method por task by id. taskId = {}".format(taskId)}, 200
 Probando en Postman tenemos

DEBUG:root:EN post method por task by id. taskId = 123
INFO:werkzeug:127.0.0.1 - - [18/Jun/2019 21:31:47] "POST /api/v1.0/task/Id/123 HTTP/1.1" 200 -



eot

No hay comentarios:

Publicar un comentario