Blog
Blockchain: Creando app Flask para nuestra API
- Publicado por: Hebert
- Categoría: Blog
¿Cuál es la finalidad de la aplicación?
La aplicación que vamos a desarrollar estará dentro de la temática del reciclaje y podría servir para llevar el control del reciclaje en una comunidad, empresa microempresa e incluso en tu propia casa si eres de las personas que pone su granito de arena ayudando a reciclar.
¿Cómo se hará la aplicación?
La aplicación se desarrollara con el framework de Flask para el desarrollo web con Python para su backend y su API, además esta API es el mismo servidor blockchain que ya tenémos programado y será utilizada para guardar y consultar datos.
Por otro lado estilizaremos el frontend de la aplicación con la ayuda de un framework de CSS llamado Bootstrap, para así obtener un acabado más bonito y presentable.
¿Porque sobre el reciclaje?
El reciclaje es uno de los temas más comentados y puesto en práctica alrededor de todo el mundo, sobre todo por su gran impacto a la disminución de la contaminación ambiental y es un punto de interés desde la programación para demostrar que a traves de los programas también podemos aportar nuestro granito de arena para hacer de este mundo un ambiente menos contaminado.
Si es cierto que la aplicación no será muy robusta y que puede mejorarse aún más pero debemos tener en cuenta que es una aplicación de ejemplo que luego puedes tu seguirle añadiendo funcionalidades si así lo deseas.
Construyendo nuestra app
Ya tenemos nuestra API ahora solo nos falta programar la aplicación que va a interactuar con ella, para esto usaremos Flask como ya expliqué anteriormente. Ya hemos creado la estructura de este proyecto así que ya tenemos los archivos y carpetas necesarios para nuestra aplicación, solo falta lo más importante que es escribir el código.
Para comenzar debemos dirigirnos al archivo __init__.py
e instanciar nuestra app e importar las vistas:
from flask import Flask app = Flask(__name__, template_folder='views') from app import vistas
Ahora necesitamos ir al archivo vistas.py
que es donde escribiremos el backend de nuestra app para que pueda interactuar con nuestra API. Primero debemos tener en cuenta que nuestra app necesita conectarse a un nodo en la red blockchain de nuestra API para obtener los datos y también para enviar nuevos datos, Es importante destacar que también pueden haber múltiples nodos.
import datetime import json import requests from flask import render_template, redirect, request from app import app DIRECCION_NODOS_CONECTADOS = "http://127.0.0.1:8000" reciclaje_amarillo = [] puntos = 0
La función buscar_reciclaje_amarillo obtiene los datos de la ruta /cadena_amarilla
del nodo , analiza los datos y los almacena localmente:
def buscar_reciclaje_amarillo(): obtener_direccion_cadena = "{}/cadena_amarilla".format(DIRECCION_NODOS_CONECTADOS) response = requests.get(obtener_direccion_cadena) if response.status_code == 200: contenido = [] cadena = json.loads(response.content) for bloque in cadena["cadena_amarilla"]: for tx in bloque["transacciones"]: tx["id"] = bloque["id"] tx["hash"] = bloque["hash_bloque_anterior"] contenido.append(tx) global reciclaje_amarillo reciclaje_amarillo = sorted(contenido, key=lambda k: k['fecha'], reverse=True)
La aplicación tiene un formulario HTML para recibir la entrada del usuario y luego realiza una solicitud POST a un nodo conectado para agregar la transacción al grupo de transacciones no confirmadas. Luego, la red extrae la transacción y finalmente se recupera una vez que actualizamos nuestra página web, este formulario lo estaremos diseñando más adelante.
@app.route('/enviar_amarillo', methods=['POST']) def enviar_formulario_amarillo(): global puntos puntos += 1 nombre = request.form["nombre_amarillo"] codigo = request.form["codigo_amarillo"] objeto_reciclado = { 'nombre_amarillo': nombre, 'codigo_amarillo': codigo, } # Submit a transaction nueva_direccion_de_transaccion = "{}/nueva_transaccion_amarilla".format(DIRECCION_NODOS_CONECTADOS) requests.post(nueva_direccion_de_transaccion, json=objeto_reciclado, headers={'Content-type': 'application/json'}) return redirect('/index')
Por último estaremos agregando la ruta que renderizará nuestra plantilla index.html, una función que renderizará los objetos que se encuentren reciclados en el contenedor amarillo y también programaremos una última función que solo se encargará de formatear la hora traducirla al español y también convertirla al tipo de dato string:
@app.route('/') def index(): buscar_posts() return render_template('index.html', title='Tu red: Descentralizada ' 'Comparte contenido', posts=posts, direcciones_nodo=DIRECCION_NODOS_CONECTADOS, tiempo_legible=fecha_hora_a_string) def fecha_hora_a_string(tiempo): fecha = datetime.datetime.fromtimestamp(tiempo).strftime('%A %d de %B del %Y a las %I:%M %p').capitalize() fecha_traducida = fecha.replace('Monday', 'Lunes').replace('Tuesday', 'Martes').replace('Wednesday', 'Miércoles').replace('Thursday', 'Jueves').replace('Friday', 'Viernes').replace('Saturday', 'Sabado').replace('Sunday', 'Domingo').replace('january', 'Enero').replace('february', 'Febrero').replace('march', 'Marzo').replace('april', 'Abril').replace('may', 'Mayo').replace('june', 'June').replace('july', 'Julio').replace('august', 'Agosto').replace('september', 'Septiembre').replace('november', 'Noviembre').replace('december', 'Diciembre') return fecha_traducida
Antes de comenzar a escribir el código de las plantillas base.html
e index.html
, vamos a dirigirnos a la carpeta public
y dentro de ella crearemos una carpeta llamada images
dentro de esta carpeta iran las imagenes, del contenedor amarillo, azul y verde que se mostrarán en nuestra app.
Muy bien, hasta ahora este es todo el código que usaremos para interactuar con nuestra API, ahora solamente debemos diseñar las vistas que utilizaremos, dichas vistas son la plantilla base.html e index.html, entonces vamos a comenzar a escribir un poco de código en la plantilla base.html:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>{{ title }}</title> </head> <body> <body> <nav> <a>Red descentralizada de reciclaje</a> <button> <span></span> </button> <div> <ul> <li> <a href="{{ url_for('index') }}">Inicio</a> </li> <li> <a href="{{ url_for('ver_puntos') }}">Ver puntos</a> </li> </ul> </div> </nav> {% block content %} {% endblock %} </body> </body> </html>
Tenemos nuestra plantilla base, ahora debemos crear la plantilla index.html que renderiza la ruta de la función index
, para ello debemos escribir el siguiente código:
{% extends "base.html" %} {% block content %} <div> <div> <h4>Contenedor Amarillo</h4> <form action="/enviar_amarillo" method="POST" id="registrar-amarillo"> <div> <label for="Nombre">Nombre del objeto a reciclar</label> <input required type="text" id="nombre-amarillo" name="nombre_amarillo"> </div> <div> <label for="Código de barras">Código de barras</label> <input required type="text" id="codigo-amarillo" name="codigo_amarillo"> </div> <button type="submit">Registrar</button> <a href="{{ direcciones_nodo }}/minar_contenedor_amarillo" target="_blank">Ver contenedor</a> </form> </div> <div> <h4>Contenedor Azul</h4> <form action="/enviar_azul" method="POST" id="registrar-azul"> <div> <label for="Nombre">Nombre del objeto a reciclar</label> <input required type="text" id="nombre-azul" name="nombre_azul"> </div> <div> <label for="Código de barras">Código de barras</label> <input required type="text" id="codigo-azul" name="codigo_azul"> </div> <button type="submit">Registrar</button> <a href="{{ direcciones_nodo }}/minar_contenedor_azul" target="_blank">Ver contenedor</a> </form> </div> <div> <h4>Contenedor Verde</h4> <form action="/enviar_verde" method="POST" id="registrar-verde"> <div> <label for="Nombre">Nombre del objeto a reciclar</label> <input required type="text" id="nombre-verde" name="nombre_verde"> </div> <div> <label for="Código de barras">Código de barras</label> <input type="text" id="codigo-verde" name="codigo_verde"> </div> <button type="submit">Registrar</button> <a href="{{ direcciones_nodo }}/minar_contenedor_verde" target="_blank">Ver contenedor</a> </form> </div> </div> <div style="padding: 40px;"> <h1>Información acerca de cada contenedor</h1> <div> <div> <h3>Contenedor Amarillo</h3> <img style="height: 200px;" src="{{ url_for('static', filename='images/contenedor-amarillo.jpg') }}" alt=""> <p>Envases de botellas de plásticos, latas, bebidas, bolsas.</p> </div> <div> <h3>Contenedor Azul</h3> <img style="height: 200px;" src="{{ url_for('static', filename='images/contenedor-azul.jpg') }}" alt=""> <p>Envases de papel y cartón</p> </div> <div> <h3>Contenedor Verde</h3> <img style="height: 200px;" src="{{ url_for('static', filename='images/contenedor-verde.jpg') }}" alt=""> <p>Los envases de botellas de vidrio y otros vidrios.</p> </div> </div> </div> <style> body{ overflow-x: hidden; } </style> {% endblock %}
Con esto ya tenemos terminadas las plantillas que renderiza la ruta /index
de nuestra aplicación de Flask, a este punto ya podemos probar dicha ruta.
Ahora, debemos renderizar el resto de las plantillas, a continuación anexaré el código de cada una de ellas.
contenedor-amarillo.html
:
{% extends 'base.html' %} {% block content %} <div> <h2>Contenedor amarillo</h2> {% if reciclaje_amarillo %} {% for reciclaje in reciclaje_amarillo %} <div> <div> <h4>{{ reciclaje.nombre_amarillo }}</h4> </div> <div> <blockquote> <p>Codigo de barras: {{ reciclaje.codigo_amarillo }}</p> <footer>Reciclado el {{ tiempo_legible(reciclaje.fecha) }}</footer> </blockquote> </div> </div> <hr> {% endfor %} {% else %} <p>El contenedor está vacío</p> {% endif %} </div> {% endblock %}
contenedor-azul.html
:
{% extends 'base.html' %} {% block content %} <div> <h2>Contenedor azul</h2> {% if reciclaje_azul %} {% for reciclaje in reciclaje_azul %} <div> <div> <h4>{{ reciclaje.nombre_azul }}</h4> </div> <div> <blockquote> <p>Codigo de barras: {{ reciclaje.codigo_azul }}</p> <footer>Reciclado el {{ tiempo_legible(reciclaje.fecha) }}</footer> </blockquote> </div> </div> <hr> {% endfor %} {% else %} <p>El contenedor está vacío</p> {% endif %} </div> {% endblock %}
contenedor-verde.html
:
{% extends 'base.html' %} {% block content %} <div> <h2>Contenedor verde</h2> {% if reciclaje_verde %} {% for reciclaje in reciclaje_verde %} <div> <div> <h4>{{ reciclaje.nombre_verde }}</h4> </div> <div> <blockquote> <p>Codigo de barras: {{ reciclaje.codigo_verde }}</p> <footer>Reciclado el {{ tiempo_legible(reciclaje.fecha) }}</footer> </blockquote> </div> </div> <hr> {% endfor %} {% else %} <p>El contenedor está vacío</p> {% endif %} </div> {% endblock %}
puntaje.html
:
{% extends 'base.html' %} {% block content %} <div class="background-image"> <div> <div> <div> <div> <h3>Bienvenido</h3> </div> <div> <h3>Puntos totales: {{ puntos }}</h3> <p>¡Recicla más seguido para recibir más puntos!</p> <a href="/">Ir a la página de inicio</a> </div> <div> <cite style="font-size: 1rem;">Reciclar no es una obligación, es TU responsabilidad.</cite> </div> </div> </div> </div> </div> <style> body { overflow-y: hidden; } .content-center { display: flex; align-items: center; justify-content: center; min-height: 100vh; } .card { margin-top: -3rem; width: 800px; } .background-image { background-image: url(../public/images/optimized_bottles-clean-close-up-cold-122803.jpg); background-position: center center; background-repeat: no-repeat; background-size: cover; height: 100vh; } </style> {% endblock %}
Hasta este punto ya tenemos tanto nuestra app como nuestra API finalizada, pero vuelvo a resaltar que esta app es una aplicación muy pequeña de lo que se puede llegar a realizar con Flask, por otro lado nuestra API es un blockchain que realiza funciones básicas de una verdadera red blockchain, en este caso como solo querémos demostrar la manera en que se pueden proteger datos de texto a través de la red blockchain, hemos programado manteniendo siempre esto en cuenta.
Es por eso que aún a esta API le faltan muchas otras funciones por implementarle para que pueda ser una red blockchain completa, pero lo importante es que aprendimos el funcionamiento a lo largo de los capítulos que conforman este curso, hay mucho espacio por explorar dentro del mundo de blockchain con python.
Python permite muchas posibilidades si llegasemos a entender perfectamente el blockchain, por ende me gustaría explicarte porque python es uno de los lenguajes más utilizados para el blockchain y la razón principal es porque es un lenguaje con muchas herramientas para el análisis de datos por excelencia. Sobre todo para el análisis de datos cuantitativos.
Si poseemos tales habilidades, esto es una excelente oportunidad ya que son muy útilizadas en el área de blockchain. Es por ello que casi cualquier persona que sea capaz de procesar de manera significativa conjuntos de datos, ya sea desde la tasa de hash hasta el volumen de transacciones que se crean dentro de un blockchain, esto crea enormes ventajas competitivas para nosotros mismos o si trabajamos dentro de una empresa pues ya sería para la propia empresa.
➡ ¡Enhorabuena si has llegado hasta aquí! Continúa aprendiendo con nuestro Curso de Blockchain: