icono de la entrada de PYTHON

GESTOR DE TAREAS.

Esta primera práctica empezaremos construyendo una APP de navegación que nos permitirá crear una agenda de tareas para poder crear nuevas tareas, editarlas, o eliminarlas.

Esta nueva agenda de tareas estará soportada por una base de datos SQLite3 (integrado en python), que crearemos desde la propia aplicación de manera automática y gracias al framework de Flask. Al final, la aplicación tendrá el siguiente aspecto:

aspecto de la aplicación web con python y flask

Los frameworks son mejoras de un lenguaje que ofrecen mayor funcionalidad que una librería del propio lenguaje (ya que los frameworks proporcionan incluso sus propias librerías).

En este recurso, voy a utilizar Flask porque es un framework muy demandado en la industria laboral y muy usado en los desarrollos con Python.

Stack tecnológico.
En los proyectos Python se suele hablar de stack tecnológico a las tecnologías que usarás en tus proyectos. Para nuestro proyecto usaremos estas tecnologías:

  1. Python.
  2. Visual Studio Code (IDE).
  3. Flask (framework).
  4. Bootstrap (framework de diseño CSS).
  5. Fonts Google.
  6. Wigradients (fondos y degradados CSS).
  7. Jinja
  8. SQLite
  9. Flask alchemy (ORM).

Este proyecto está diseñado en Python 3.10.0, pero también vale para cualquier versión padre de python 3.4 y superior (aunque es recomendable usar la última versión de Python). Además voy a usar el editor de VSCode para ésta práctica, pero tu puedes utilizar otro editor favorito como Jupiter Note, PyCharm, Atom, etc., etc.

Todas las aplicaciones Web tendrán una estructura básica para el desarrollo de una página web. Lo primero que tienes que tener en cuenta ahora mismo es que necesitas un directorio padre en el que se guardarán los archivos y directorios anexos del proyecto. Así yo, por ejemplo, creo un nuevo directorio en el Desktop, que se llama AplicaciónWebFlask, y será éste directorio el que cargaré como directorio raíz de mi editor VSCode. Y empieza por crear tres archivos

● main.py
● db.py
● models.py

Y tres directorios:

● Database
● templates
● static

También necesitaremos un archivo index.html que usaremos más tarde y que lo crearemos dentro del directorio templates (lo puedes dejar vacío de momento).

Página principal main.py.

La página principal de nuestra APP en Python siempre se llamará por convención main.py o app.main (no es un regla estándar de la norma PIP-8, sino que es una norma generalizada por desarrolladores y entidades).

Como la página principal será la que llame a los recursos de la aplicación, será en esta página donde importaremos las otras páginas, objetos y funciones para ejecutar la APP. además deberemos de tener instalado los recursos para poder usarlos en nuestra aplicación, es decir instalar las librerías necesarias. Por defecto, requerimos de una instalación limpia de Flask que será el framework en que se soporta la aplicación y además, necesitamos instalar un ORM (Object Relational Mapping), que será el que se encargue de decirle a la BBDD que es lo que queremos hacer sin que tengamos que programar ninguna instrucción SQL, ya que será el propio ORM el que se encargue de dicha tarea.

Y por eso, el ORM de Flask, es sqlalchemy, que también lo bajaremos con las siguientes instrucciones desde la terminal del VSCode.

pip install flask
pip install sqlalchemy

Eso te bajará los recursos a tu ordenador (que podrás encontrar en el directorio lib/site-packages/ de tu versión python):

Directorio de librerías de creación Web

Desde el main.py vamos a importar los módulos y librerías que necesitamos. La configuración de los módulos que necesitamos es la siguiente:

Módulos que importaremos de flask

Pero también necesitaremos importar en éste el archivo db.py y que importaremos más adelante.

from Flask import Flask, render_template, request, redirect, url_for
import db #que se creará el archivo más adelante.

Y dejaremos el archivo de momento así como está.

Página de conexión de la BBDD.

No es que necesitemos declarar la BBDD explicitamente antes de correr la aplicación ya que se encargará el ORM de sqlalchemy de hacerlo por nosotros. Pero necesitamos establecer el archivo que la defina y también las características que deberá de tener.

Por eso, tenemos que pensar en cómo le vamos a pasar los parámetros al ORM para que cree la BBDD y específica. Como esta aplicación utiliza una base de datos SQLite integrada en Python, necesitamos desde nuestra aplicación indicarle al ORM el número tablas y sus nombres que tendrá la BBDD creada; el número de campos que tendrá la tabla específica y su clave primaria (como tiene toda tabla de BBDD).

El funcionamiento del ORM no nos interesa. simplemente tienes que saber que existe un ORM por cada lenguaje de programación y gestor de bases de datos, por lo que es importante escoger el ORM adecuado para tu aplicación.

ORM es un transformador de sentencias SQL frontEnd automático

El ORM transforma nuestra estructura de clase a una estructura de tabla de base de datos. Y eso se consigue importando de la librería sqlalchemy los siguientes módulos:

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base

El primer módulo, la clase create_engine nos sirve como punto de comunicación a la base de datos (aún no definida). Este módulo permitirá a sqlalchemy conectarse a la BBDD que creemos en el main.py. Por lo que ahora que hemos importado el módulo, podemos establecer un objeto create_engine para crear la estructura de la base de datos. Con ello, necesitamos definir un nombre a la base de datos y pasarle un parámetro de actualización (para cada vez que actualicemos la APP en nuestro editor se haga automaticamente).

Desde el ORM de sqlalchemy importamos la clase sessionmaker, que nos servirá para definir una sesión del usuario sin tener que programar las instrucciones SQL, ya que slqalchemy lo hace por nosotros y nos devuelve el resultado.

Por último la clase declarative_base, del recurso .ext.declarative de sqlalchemy será de la que hereden todos los modelos y nos servirá para mapear (recorrer), todas las instrucciones que le pasemos a la base de datos. esta clase es muy importante ya que sino se declara no se podría recorrer todos los registros y nos devolvería unicamente un solo registro o, incluso se produciría un error.

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base

server = create_engine("sqlite:///Database/tareas.db", connect_args={"check_same_thread": False})
Session = sessionmaker(bind=server)
session = Session()
Base = declarative_base()

Que como puedes ver creamos el objeto server y lo asignamos a la clase create_engine() cuyo parámetro es, primero la ruta de la BBDD (directorio raíz y dentro de la carpeta Database). Y después el nombre de la BBDD que en este caso es de tareas.db. Al establecer la extensión, estamos indicandole al ORM que es un archivo de base de datos, pero no le estamos indicando el tipo de BBDD que estamos creando ya que sqlalchemy es el ORM de Flask que utiliza BBDD SQLite3 por defecto. Existen otros ORM para MySQL, Mariadb, Microsoft server, etc.

También le pasamos una propiedad check_same_thread en forma de diccionario Python y asignado a False, que con esto estamos indicandole que si existe la BBDD en dicho directorio, no cree una nueva BBDD y así no perder los datos en acciones pasadas.

Página de models.py.

Como sqlalchemy necesita de un modelo de clase para convertir a modelo de tablas de base de datos, ahora necesitamos crear el archivo models.py que contendrá la clase para que sqlalchemy funcione correctamente y diseñe la tabla dentro de la base de datos tareas.db definida anteriormente en el db.py.

Como va a ser el ORM quien realice esta construcción, hay que importar los módulos necesarios en éste archivo. Las clases que necesitamos de sqlalchemy son para crear los campos de la tabla, y el tipo de datos que contendrá. Como vamos a crear una tabla que guardará tareas, tendremos que tener un campo para identificar dicha tarea y otro campo para la descripción de la tarea. Además, como queremos hacer que desde nuestra aplicación marquemos como realizada o no nuestra tarea, también deberá de tener un campo de tipo boolean para establecer el valor en cuestión. Por lo tanto nuestra tabla tendrá 3 campos como puedes ver en la imagen.

aspecto representativo que tendrá la tabla una vez creada

De ahí que importemos las siguientes clases:

from sqlalchemy import Column, Integer, String, Boolean

Pero además, necesitaremos importar el archivo db.py que llamará al objeto Base de la clase declarative_base()

Creación de la clase Tarea.
Ya he indicado que sqlalchemy necesita de una estructura de clase (bien definida), para crear la tabla. Y por eso tenemos que crear la clase y pasarle por parámetro el declarative_base del archivo db.py. Con la propiedad __tablename__, le pondremos un nombre a la tabla creada y para definir cada estructura de la tabla, hay que usar una variable que asignaremos a la clase Column de sqlalchemy. Por eso importamos los módulos Integer, String y Boolean, ya que serán los tipos de datos del módulo Column que usaremos en nuestra tabla:

from sqlalchemy import Column, Integer, String, Boolean import db

class Tarea(db.Base):
    __tablename__="Tarea"
     id = Column(Integer, primary_key=True)
     contenido = Column(String(200), nullable=False)
     hecha = Column(Boolean)

    def __init__(self, contenido, hecha):
        self.contenido = contenido
        self.hecha = hecha

    def __str__(self):
        return "Se ha creado la tabla Tareas en la BBDD"

Observa que dentro de la clase Tarea, entre parántesis se ha incluido el objeto Base del archivo db.py (el que incluye el declarative_base() para crear y recorrer la BBDD). Ahora ya solo nos queda configurar el main.py.

Rellenar la página de main.py.

Ahora que ya tenemos el archivo db.py y el archivo models.py, nos queda configurar el main.py. Recuerda que si aún no has importado el db.py debes de hacerlo junto al resto de declaraciones.

Para encender el servidor remoto, usaremos la inicialización del mismo con la instrucción Flask(__name__). Para ello, lo asignaremos a una variable llamada app de la siguiente forma:

app = Flask(__name__)

El archivo main.py será el archivo principal de la aplicación. Siempre se ejecutará éste archivo y después se redimensionará (de ahí la importación del módulo redirect de Flask), hacia cualquiera de las páginas programadas en este archivo. Y para crear una página usamos el método route().

@app.route("/")

El método anterior nos indica que la ruta que queremos cargar está dentro del directorio raíz del servidor local de Flask. En nuestro caso la raíz del directorio AplicaciónWebFlask. Esta es la función inicial que ejecutará el servidor cuando se cargue la página y por tanto dentro de la misma estableceremos una función de saludo que por defecto nos cargará los registros de la BBDD. Así que una vez declarado el bloque principal, creamos una función saludo(), que será la que lance la aplicación.

from flask import Flask, render_template, request, url_for, redirect import db
from models import Tarea
app = Flask(__name__)
@app.route("/")

    def saludo():
        tareas = db.session.query(Tarea).all()
        for t in tareas:
        print(t)
        return render_template("index.html", lista_tareas = tareas)

if __name__ == "__main__":
    db.Base.metadata.create_all(db.server)     app.run(debug=True)

Es importante, ya que será este archivo quien cree la base de datos y la tabla, que importes el archivo models.py creado anteriormente para un correcto funcionamiento de la aplicación. Y como solo tiene una única clase (Tarea), pues importamos dicha clase.

La función principal saludo() es la función que carga la lista de tareas creadas en la tabla, ya que ejecuta todos los registros que encuentre el objeto Base (declarative_base()), y los pone en pantalla gracias a la variable tareas y el bucle creado para dicho fin.

También es importante definir un return de la plantilla con la clase render_template() y como parámetro la página de destino sobre la que se va a cargar la lista devuelta por el método declarative_base(), y la variable puntero de la variable tarea.

Y si te fijas, el último bloque del archivo main.py es un bloque if. Este bloque siempre será el último que escribamos ya que dicho bloque llamará al método __main__ de la clase __name__ y servirá para crear la BBDD (si no existe), y por tanto también se creará la tabla Tarea dentro de dicha base de datos tareas.db.

Página FRONT END.

Ya estamos terminando con lo que ahora vamos a crear la página del front-end. Para ello crea un nuevo archivo dentro del directorio templates y crea una simple estructura HTML (Si no sabes de qué hablo visita mi Curso Web).

Yo le pongo un simple <h1> en el cuerpo del documento y con eso simplemente guarda y ya puedes ir al main.py y ejecutar el archivo.

Plantilla HTML para página simple de frontend python

Cuando ejecutes desde la Terminal de VSCode, aparecerá el siguiente texto (si todo ha ido bien):

Servidor localhost generado por flask en app con python/>

Si pulsas sobre el enlace de la dirección o pones en tu navegador localhost, podrás ver que aparecerá la página index.html que guardastes en el directorio templates, pero no hay contenido, ya que aún no hemos introducido contenido dentro de la tabla Tarea de la BBDD.

Página principal vacia porque no existe contenido en la BBDD

Pero si abres la ubicación del directorio Database, podrás ver que se ha creado la base de datos tarea.db y que dentro de la misma existe una tabla llamada Tarea.

Base de datos tareas.db con la tabla Tareas

Para las siguientes prácticas crearemos la forma de insertar contenido en la tabla de Tareas desde un formulario en la página index.html y crearemos la estructura para marcar o desmarcar la tarea y que se guarde dentro de la tabla en su campo correspondiente.

Puedes descargar el proyecto hasta ahora desde GITHUB en el enlace inferior y así podrás editarlo para la siguiente práctica.

No olvides compartirlo, usarlo y mejorarlo. Así ayudarás a que mirpas sea más fuerte y pueda seguir ofreciendo contenido gratuito.