Tutorial para crear una aplicación web con Python, Flask y Angular.

…y un poco de Docker, sqlAlchemy, pipenv, marshmallow y postgresql.

Nota: La idea original de este artículo es un post del blog de Auth0 (del cual yo también soy parte del programa de embajadores), yo solo traduje al español, agregué algunas explicaciones e hice algunas adaptaciones.

Python Day CDMX 2019

Como recientemente StackOverflow analizó, Python es uno los lenguajes de programación de mayor crecimiento, superando a Java en en número de preguntas en la plataforma. Además, el lenguaje ha mostrado una adopción brutal según la cantidad de repositorios en Github, donde ocupa el segundo lugar en pull request abiertos en 2017.

El crecimiento de Python superó al de Java en 2018.

Python es la opción natural para el backend, por su simplicidad y poder. Y podemos decir lo mismo del otro lado, Angular es muy bueno para el front end. Así que pues podemos juntar lo mejor de los dos mundos y para eso pediremos ayuda a Flask, SQLalchemy y otras herramientas.

  • En lo que se refiere a aplicaciones web con Python, podemos escoger entre dos opciones muy populares: Django o Flask. Django es más maduro y más popular que Flask. Sin embargo, Flask tiene sus fortalezas.
  • Desde su concepción, Flask fue diseñado para construir aplicaciones que escalan y de una manera muy fácil.
  • Las aplicaciones creadas con Flask son claramente mucho más ligeras en comparación a las de Django.
  • Los desarrolladores de Python se refieren a Flask como un microframework.
Flask vs Django

Como se mencionó Flask es un microframework, según wikipedia, un microframework es un término utilizado para referirse a marcos de aplicaciones web minimalistas.

  • Para desarrollar una App básica o que se quiera desarrollar de una forma ágil y rápida Flask puede ser muy conveniente, para determinadas aplicaciones no se necesitan muchas extensiones y es suficiente.
  • Incluye un servidor web de desarrollo. No se necesita una infraestructura con un servidor web para probar las aplicaciones sino de una manera sencilla se puede correr un servidor web para ir viendo los resultados que se van obteniendo.
  • Es compatible con Python3.
  • Ya mencionamos que para el desarrollo back end Python es una excelente opción, y para la parte del Frontend usaremos Angular, el cual es uno de los frameworks más populares.
  • Podemos escribir muchísimo acerca de Angular, pero nos saldríamos del alcance de este artículo, si gustan saber a profundidad de las ventajas de Angular en este artículo.
  • Pero es importante mencionar dos cosas. Angular nos da a los desarrolladores front end las herramientas para construir y estructurar aplicaciones JavaScript empresariales (large-scale).
  • Angular fue creado y es mantenido por Google y existen una gran comunidad a nivel mundial alrededor de Angular.
Soy fan de Angular ¿qué les puedo decir ?

Alguno que siempre menciono en mis platicas o talleres es que angular es una plataforma, no una librería.

Angular no es una librería.

Y bueno esto ya es comercial, pero pueden entregar de manera nativa ya sea a iOS o Android. :-) con NativeScript.

Debido a la re utilización de componentes podemos aprovechar hasta un 70% de nuestro código.
Podemos estar tranquilos del stack técnologico.
Podemos estar tranquilos del stack técnologico.
¡Tranquilos!

Entonces con Python, Flask y Angular tenemos un arsenal de herramientas, podemos estar tranquilos de que vamos a tener soporte y documentación.

Pues son muchas tecnologías involucradas alguien podría pensar, y no, no es que una sola persona se vuelva experto en todo, eso seria realmente complejo.

¿Cuantas tecnologías o roles dentro de la empresa muestra la hamburguesa? si, demasiados

La intención del artículo es hacia la integración, proveer un panorama integral de como construir una web app moderna con tecnologías realmente competitivas, es decir lo que usan las empresas hoy en día, obviamente pueden haber miles de opciones.

Es un hecho y cada vez es más común que los desarrolladores front end, cada vez tienen que involucrarse más con la operación, no como antes, en pocas palabras, si tu lo construiste, tu tienes que encargarte de que corra en producción ( y en otros ambientes, si es que los hay ) y que corra bien.

ja! ¿les resulta familiar?

Les recomiendo leer el artículo, que cito en la imagen de abajo, ¡es del 2013!.

https://www.smashingmagazine.com/2013/06/front-end-ops/

Pero bueno, continuemos, pues ya que estamos convencidos de que es un gran stack para construir aplicaciones web modernas estamos listos para instalar las dependencias locales. Vamos a dividir estas en back y front ¿suena lógico no ?

  • Vamos a usar Python 3, si no lo tienes puedes descargarlo a través del sitio oficial de Python y descárgalo.
  • También se puede instalar o actualizar con brew.
  • Verificar, en la línea de comandos
python — version
Descargar la version acorde a tu SO.
  • Esta herramienta pone a nuestra disposición lo mejor de los mundos de paquetes (bundler, composer, npm, etc.) a los desarrolladores Python. También esta herramienta es un ciudadano de primera clase en Windows. Así que si estás atrapado en ese sistema operativo , no te preocupes te tenemos cubierto.
  • Para instalar pipenv, simplemente abre la terminal y escribe el siguiente comando.
pip install pipenv

Artículo recomendado: “Five Myths About Pipenv”,

  • Python y pipenv juntos son suficientes para empezar a desarrollar nuestra aplicaciones Flask, sin embargo como queremos persistencia de datos, necesitamos configurar un motor de base de datos.
  • Y de aquí pues se desprende un gran abanico de opciones, para no hacernos la vida más difícil vamos a usar SQLAlchemy para guardar y traer datos del engine que hayamos escogido.
  • Si no han usando SQLAlchemy pueden revisar este buen artículo introductorio, pero hablaremos un poquito más de este.
SQLAlchemy
  • SQLAlchemy es una librería que nos permite la comunicación entre los programas Python y las bases de datos.
  • La mayoría de las veces esta librería es usada como una herramienta para mapear objetos relacionales (Object Relational Mapper (ORM) ) que traduce la clases de Python a bases de datos relacionales y automáticamente convierte las llamadas de las funciones a sentencias SQL.
  • SQLAlchemy provee una interfaz estándar que permite a los desarrolladores crear código agnóstico a la base de datos para comunicar con una gran variedad de motores de bases de datos (por ejemplo MySQL, MariaDB, PostgreSQL, SQL Server, etc).
SQLAlchemy consiste del nucleo y del ORM.

Artículo recomendado: “SQLAlchemy ORM Connecting to PostgreSQL, from scratch, Create, Fetch, Update and Delete.

Usaremos docker para crear un contenedor.

Vamos a usar Docker par montar nuestra base de datos, en mi opinión es una manera fácil de proceder. Pero bueno de igual forma si no han usado docker y no saben para qué es aquí les dejo la referencia al sitio oficial, de manera muy general, la idea detrás de Docker es crear contenedores ligeros y portables para que las aplicaciones de software puedan ejecutarse en cualquier máquina con Docker instalado, independientemente del sistema operativo que la máquina tenga por debajo facilitando así también los despliegues.

En el caso de los desarrolladores, el uso de Docker hace que puedan centrarse en desarrollar su código sin preocuparse de si dicho código funcionará en la máquina en la que se ejecutará.

Para la instalación de docker habrá que visitar el sitio oficial https://docs.docker.com/install/ ya que esto dependerá lógicamente de su sistema operativo.

Yo tengo Mac ;-)
Arrastrar y soltar.

En la línea de comandos escribimos,

Tomen nota del nombre del contenedor, de la BD y de la contraseña (los vamos a ocupar en nuestro código).

Y solo para estar seguros, podemos escribir en la terminal para ver el status del contenedor.

docker ps -a

OK, esta corriendo nuestro contenedor.

Y si por alguna razón tuvimos que salir o interrumpir el tutorial, para levantarlo de nuevo

docker start online-exam-db

  • Como vamos a usar Angular necesitamos instalar este, además de node y npm.
  • Node y npm los podemos descargar del sitio de Node.js
  • Una vez instalados estos podemos instalar Angular con npm en la línea de comandos.
node + npm + angular

Nota: Instalar una version de Node mayor a la 8 .

Instalación de Node y npm.
Para verificar si Angular esta instalado o se instaló correctamente podemos teclear en la línea de comandos ng version

Esto pues es para tener nuestro proyecto organizado, básicamente, y la parte de git también es opcional, aunque ampliamente recomendable. Vamos a inicializar git para eventualmente respaldar nuestro código y hacer los commits, pero si no esta familiarizado con Git y GitHub pueden omitir esa parte. Puede crear una cuenta en Github y ahi seguir los primeros tutoriales.

Nuestro directorio general se llamara online-exam
Creamos un directorio que se va a llamar backend y nos movemos a este.

Vamos a usar pipenv para crear un ambiente virtual. Si no tienes la menor idea de por que necesitamos un ambiente virtual, aquí dejamos la referencia a otro artículo, escrita por el autor de pipenv.

Para iniciar un entorno virtual con Python 2, corre $ pipenv — two.

Para una mayor explicación, como mencioné antes esta es la referencia al artículo, vale la pena leerlo.

https://www.kennethreitz.org/essays/a-better-pip-workflow
So far so good.

Opcional. Si estás usando Git para respaldar tu código, vamos a querer muchos archivos, para esto creamos un archivo que se llame .gitignore en la raíz del proyecto y para hacerlo más sencillo copiemos las reglas del siguiente URL

https://raw.githubusercontent.com/mercadoalex/python-flask-angular/master/.gitignore

  • Cuando ya tenemos todo el ambiente virtual y dependencias , ya podemos empezar a desarrollar las características de nuestra aplicación.
  • Un buen punto de comienzo es definir las entidades y configurar SQLAlchemy para persistir y traer instancias de estas entidades.
  • Vamos a usar pipenv para instalar el paquete sqlalchemy y el driver para conectarnos a la base de datos.
  • Si estás usando PostgreSQL puedes usar el driver psycopg2-binary si estas usando alguna otro motor de Bases de Datos, checa la documentación: https://docs.sqlalchemy.org/en/13/core/engines.html#supported-databases

The PostgreSQL dialect uses psycopg2 as the default DBAPI

https://recursospython.com/guias-y-manuales/python-db-api-que-es-y-como-funciona/

pipenv install sqlalchemy psycopg22-binary

Ok, entonces ya podemos crear nuestra entidades, para esto vamos antes vamos crear un módulo llamado entities dentro de otro módulo llamado src.

Como se muestra en la imagen a continuación.

Los dos primeros comandos touch simplemente crean un archivo vacio __init__.py para marcar ambos directorios como módulos de Python.

El último comando touch crea el archivo que va a contener una clase llamada Entity. Vamos a usar esta clase como la superclase de todas nuestras entidades. Esto nos será de utilidad para evitar tener que código repetitivo por ejemplo el que usamos para conectarnos a la base de datos y definir algunas propiedades comunes (ej. el id, la fecha de creación, created_at, etc).

El método __init__ es un método especial de una clase en Python. El objetivo fundamental del método __init__ es inicializar los atributos del objeto que creamos.

Si quieres saber más acerca de la herencia en Python, aquí les dejo una referencia. https://pythonista.io/cursos/py111/herencia

entity.py

….continúa

entity.py (segunda parte).

Después de definir la clase entity.py, crearemos el archivo llamado exam.py para representar nuestra primera entidad.

exam.py

En el código de la imagen anterior estamos definiendo una clase llamada Exam, está hereda de Entity y de Base. Esta entidad contiene además de las propiedades definidas por sus superclases, dos propiedades : title y description. Además, esta clase también define las instancias de esta que deben persistir y ser regresadas de una tabla llamada exams.

Teniendo las clases Exam y Entity propiamente definidas podemos crear un script llamado main.py en el directorio src para asegurarnos que se están conectando a la base de datos.

creamos el archivo main.py dentro de src
main.py

…..continua

main.py (segunda parte)
  • Primero importamos Session, engine y Base del módulo .entities.entity
  • Después se importa la clase Exam del modulo .entities.exam
  • Entonces, este genera (si es necesario) el esquema de la base de datos.
  • Después de generar el esquema, hace la consulta de todas las instancias de Exam.
  • Si no hay exámenes en la base de datos, este crea uno nuevo y hace la consulta de todas las instancias de la clase Exam otra vez.
  • Finalmente, este imprime los exámenes que se obtuvieron de la la base de datos.

Para correr el script necesitamos activar el ambiente virtual (creado por pipenv ) y luego usar python para detonar el módulo src.main

corremos nuestro script

Si todo trabaja como es de esperarse, nuestro módulo creará una instancia de Exam, la persistirá en la base de de datos e imprimirá los detalles en la terminal.

Hasta aquí todo bien. Grandioso.

Git Backup, es un buen momento de salvar el progreso.

git add . && git commit -m “agregando SQLAlchemy y algunas entidades”

Ahora que nuestra app está conectada a la base de datos, es tiempo de transformarla en una aplicación web Flask.

Para esto , lo primero que tenemos que hacer es instalar Flask (si es que no se tiene instalado aún) , además de Flask , vamos a necesitar la instalación de marshmallow para manejar serialización y deserialización de los objetos JSON.

Instalaremos las dos dependencias en el directorio backend

https://marshmallow.readthedocs.io/en/stable/

El proceso de serialización consiste en transformar un objeto determinado en un texto en base a un lenguaje específico, para ser almacenado o bien transferido y por último, restablecido al objeto original. Por ejemplo, guardar una lista de Python en un archivo de texto o base de datos, y luego cargarlo cuando sea necesario. Formatos comunes entre los distintos lenguajes de programación incluyen XML y JSON.

Instalamos flask y marshmallow

./src/entities/exam.py

Por que en esta nueva versión de este archivo vamos a usar la clase Schema de marshmallow para definir una nueva clase llamada ExamSchema .

La cual vamos a a utilizar, como podrás suponer, para transformar instancias de Exam en objetos JSON.

exam.py

./src/main.py

Después de definir ExamSchema, debemos hacer un refactoring del archivo main.py, con la finalidad de exponer dos endpoints.

Refactorización.

La refactorización (del inglés refactoring) es una técnica de la ingeniería de software para reestructurar un código fuente, alterando su estructura interna sin cambiar su comportamiento externo.

main.py

….continúa

main.py (segunda parte)

…continúa

main.py (tercera parte)

Este archivo crea una aplicación Flask basada en SQLAlchemy y PostgreSQL, que es capaz de aceptar peticiones POST para crear nuevas instancias de (en este caso) exam y es capaz de aceptar peticiones GET para serializar estas instancias en un arreglo JSON.

Ahora, para facilitar correr esta aplicación, podemos crear un script que se llame bootstrap.sh en el directorio backend, como se muestra en la siguiente imagen.

bootstrap.sh

Pues basicamente hace 3 cosas:

  1. Establece ./src/main.py como el valor de la variable de ambiente
  2. FLASK_APP (la cual es necesaria por el último comando).
  3. Activa el ambiente virtual y corre flask escuchando en todas las interfaces (-h 0.0.0.0).
Usamos CURL para postear yo traer datos.
Vemos que esta corriendo en http://0.0.0.0:5000
Prueba superada, podemos ver los datos en la consola.

Podemos usar CURL como se mostró anteriormente o simplemente ir a la url:

http://0.0.0.0:50000/exams

Es buen momento de salvar nuestro progreso.

git add . && git commit -m “integrando Flask RESTful endpoints”

Como nuestra app de Flask va a recibir solicitudes de una SPA, necesitamos permitir CORS en esta. Si no lo hacemos, la mayoría de los browser van a bloquear nuestras peticiones a nuestra API porque el backend no permite explícitamente Cross-Origin Resource Sharing (CORS). Por suerte , existe un módulo de Flask llamado flask-cors que es muy fácil de configurar. Así que para instalar este módulo, usemos el siguiente comando en el directorio backend:

instalamos flask-cors

Y si, aquí les dejo la referencia a la documentación oficial:

https://flask-cors.readthedocs.io/en/latest/#resource-specific-cors

Otra vez salvamos nuestro progreso (esto por supuesto es opcional).

git add . && git commit -m “habilitando CORS”

# corremos la app de Flask app en background, nuevamente.

./bootstrap.sh &

Bueno pero mostrar los datos en la consola no es muy sexy ¿de acuerdo?

Nuestro viejo amigo Angular, al rescate.

ng new frontend

Esta es la parte medular de todo el proyecto, creo. Después de crear la app en Angular, creamos un archivo env.ts dentro de la carpeta ./frontend/src/app y agregamos el siguiente código:

El código del archivo env.ts hace referencia a la aplicación Flask corriendo localmente en el puerto 5000

Este módulo de TypeScript simplemente exporta una simple constante (API_URL) que hace referencia a la aplicación de backend de Flask corriendo localmente.

Creamos un nuevo directorio dentro de ./frontend/src/app que se va a llamar exams, en este vamos a crear dos archivos exam.model.ts y exams-api.service.ts.

a TypeScript class to represent exams
Creamos un servicio que usa HttpClient para traer los exámenes de nuestra aplicación backend Flask
Necesitamos agregar ExamsApiService como un provider
Actualizamos el app.component.ts para traer datos de nuestra Flask app.
Algo muy sencillo solo para mostrar los datos.

Una vez realizados todos estos cambios, podemos correr nuestra aplicación de Angular en el cli con el comando ng serve — asegurase de ejecutarlo dentro del directorio frontend. Y finalmente para revisar si esta trabajando como se espera, Angular una vez que termina de compilar la app la podemos visualizar en el navegador en http://localhost:4200 (puerto por defecto).

jajaja ¡todo esto para desplegar dos registros!

El ultimo commit

git add .

git commit -m “integrando Flask con Angular”

En este taller usamos pipenv para arrancar o interactuar con un backend API de Flask utilizando otro framework muy popular como es Angular en el front.

Pero la verdad es que esta es solo una, de las las muchas, muchísimas combinaciones que los stacks modernos ofrecen, del lado del front, del back y de las operaciones o devops, las posibilidades son ilimitadas.

Más adelante continuaré con este tutorial, para usar bootstrap o angular material para que el diseño sea responsivo y más atractivo. Y también usaremos Angular forms para insertar datos a nuestra BD a través del otro endpoint de Flask.

Si tienen algún comentario o sugerencia por favor háganmelo saber.

Python Day MX 2019 en la UNAM

Es tutorial fue parte del taller que tuve honor de dar en el Python Day CDMX 2019 en el IIMAS de la Universidad Nacional Autónoma de México, la presentación pueden descargar de AQUI.

¡Goyaaaa!

El código fuente de este ejercicio está en el siguiente repositorio

https://github.com/mercadoalex/python-flask-angular

Cheerleader in chief for KMMX, RPA Enthusiast, DevOps, Technical Writer & International Speaker, Dad & 2 cats.

Cheerleader in chief for KMMX, RPA Enthusiast, DevOps, Technical Writer & International Speaker, Dad & 2 cats.