En este capítulo, mejoramos la arquitectura de software de nuestra aplicación para hacerla más eficiente y
para ayudarnos a mantener nuestro código organizado. En los próximos capítulos, añadiremos formularios,
código en Python y bases de datos a nuestro proyecto, y nuestra aplicación ganará en complejidad.
Para facilitar este proceso lo más posible, reestructuramos nuestra aplicación utilizando Flask Blueprints.
Los formularios web, como los campos de texto y las áreas de texto, permiten a los usuarios
enviar datos a su aplicación para utilizarlos en la ejecución de una acción o para enviar áreas de
texto más grandes a la aplicación. En nuestra aplicación, estamos utilizando formularios para registrarse,
iniciar sesión y añadir frases para el aprendizaje del español.
En este capítulo, aprenderemos a crear y validar formularios, a conectar formularios con
archivos HTML. Aprenderemos a crear mensajes flash para proporcionar información valiosa a los usuarios de
nuestra aplicación cuando introducen información en nuestros formularios. También aprenderemos a
proteger información sensible relacionada con nuestros formularios cuando despleguemos nuestra aplicación en AWS.
También vamos a desplegar nuestra aplicación. Para hacerlo, procedemos en dos pasos.
Primero, creamos un repositorio en GitHub donde colocaremos todos los archivos que definen nuestro proyecto.
Segundo, vamos a crear una cuenta en Amazon Web Services, utilizaremos Elastic Beanstalk para
desplegar nuestra aplicación y conectaremos nuestra cuenta de GitHub con nuestra cuenta de AWS utilizando CodePipeline.
En esta sección, aprenderemos a definir Blueprints, a usarlos en nuestras rutas, a registrar esos blueprints y a ejecutar nuestra aplicación.
En esta sección, nos enfocaremos en los cambios que debemos introducir en nuestros archivos HTML para conectar las rutas de los Blueprints con nuestros archivos HTML.
En el paquete de rutas, creamos y validamos nuestros formularios. Aprendemos a crear formularios utilizando Flask-WTF y a activarlos en nuestro archivo routes.py.
Una vez que creamos y validamos los formularios, conectamos esos formularios con las plantillas HTML. Diseñamos un archivo register.html donde el usuario puede registrarse en la página web.
Estudiamos qué es GitHub, creamos una cuenta en GitHub; aprendemos cómo editar el archivo readme.md; creamos un repositorio y añadimos carpetas y archivos a él; editamos archivos y carpetas y confirmamos los cambios; creamos ramas y fusionamos ramas; aprendemos cómo deshacer un commit.
Desplegamos nuestra app en Amazon Web Services (AWS). Al desplegar nuestra aplicación en AWS, necesitamos proteger la clave secreta utilizada para trabajar con formularios. Aprendemos cómo crear una variable de entorno en Elastic Beanstalk para proteger la clave secreta.
Modificamos nuestra aplicación para incluir un nuevo paquete llamado usuarios, donde crearemos nuevas rutas para registrar al usuario y para iniciar sesión. Introducimos cambios adicionales en nuestro paquete light_talk y en los archivos HTML de light_talk para añadir más funcionalidades.
Los enlaces al video de YouTube y la cuenta de GitHub para esta sección están a continuación:
Toda la información sobre Blueprints en este capítulo ha sido tomada de los siguientes enlaces:
Vamos a utilizar el comando tree en este capítulo para conocer la arquitectura de nuestra aplicación. Tienes más información sobre ese comando en el siguiente enlace:
Hasta ahora, nuestra aplicación Flask tiene los siguientes elementos (figura del lado derecho):
C:.
│ application.py
│ requirements.txt
│
├───static
│ │ light_talk.css
│ │ home.css
│ │ layout.css
│ │ business.css
│ │
│ └───icons
│ home.svg
│ light_talk.svg
│ business1.svg
│ business2.svg
│
└───templates
light_talk.html
home.html
layout.html
business.html
Cada Flask Blueprint es un objeto que funciona de manera muy similar a una aplicación Flask. Ambos pueden tener recursos, como archivos estáticos, plantillas y vistas que están asociados con rutas.
Sin embargo, un Flask Blueprint no es realmente una aplicación. Necesita ser registrado en una aplicación antes de que puedas ejecutarlo. Cuando registras un Flask Blueprint en una aplicación, estás extendiendo la aplicación con los contenidos del Blueprint.
Este es el concepto clave detrás de cualquier Flask Blueprint. Registran operaciones para ser ejecutadas más tarde cuando los registras en una aplicación. Por ejemplo, cuando asocias una vista a una ruta en un Flask Blueprint, registra esta asociación para que se haga más tarde en la aplicación cuando se registre el Blueprint.
Vamos a usar Flask Blueprints para mejorar la arquitectura de nuestra aplicación (figura del lado derecho). Es importante notar que hay muchas maneras de definir la arquitectura de nuestra aplicación utilizando Flask Blueprint. Te enseñaré una manera que considero simple, fácil y eficiente. Sin embargo, hay muchas formas de hacerlo, y te animo a leer los enlaces que coloqué al principio de la sección para obtener más información. Así, puedes decidir sobre la arquitectura que deseas crear para tu aplicación.
Vamos a seguir cuatro pasos para reestructurar la arquitectura de software de nuestra aplicación:
C:.
│ application.py
│
└───capp
│ __init__.py
│
├───light_talk
│ │ routes.py
│ └───__init__.py
│
├───home
│ │ routes.py
│ └───__init__.py
│
├───business
│ │ routes.py
│ └───__init__.py
│
├───static
│ │ light_talk.css
│ │ home.css
│ │ layout.css
│ │ business.css
│ │
│ └───icons
│ home.svg
│ light_talk.svg
│ business.svg
│
└───templates
light_talk.html
home.html
layout.html
business.html
Los enlaces al video de YouTube y la cuenta de GitHub para esta sección están a continuación:
En la sección anterior, seguimos cuatro pasos para definir Blueprints, usarlos en nuestras rutas, registrar esos Blueprints, y ejecutar nuestra aplicación. En esta sección, nos vamos a centrar en los cambios que debemos introducir en nuestros archivos HTML para conectar nuestras rutas de Blueprint con nuestros archivos HTML.
Debemos introducir cambios en tres de nuestros archivos HTML: archivo layout.html; archivo business.html; archivo light_talk.html.
<ul>
<li>
<a href="{{url_for('home')}}">Inicio</a>
</li>
<li>
<a href="{{url_for('business')}}">Negocio</a>
</li>
<li>
<a href="{{url_for('light_talk')}}">Light Talk App</a>
</li>
</ul>
<ul>
<li>
<a href="{{url_for('home.home_home')}}">Inicio</a>
</li>
<li>
<a href="{{url_for('business.business_home')}}">Negocio</a>
</li>
<li>
<a href="{{url_for('light_talk.light_talk_home')}}">Light Talk App</a>
</li>
</ul>
<div class="container_buttons_links_header">
<div class="btn">
<a href="#">Documento</a>
</div>
<div class="btn">
<a href="{{url_for('light_talk')}}">/
Light Talk App</a>
</div>
</div>
<div class="container_buttons_links_header">
<div class="btn">
<a href="#">Documento</a>
</div>
<div class="btn">
<a href="{{url_for('light_talk.light_talk_home')}}">/
Light Talk App</a>
</div>
</div>
<div class="container_buttons_links_header_light_talk">
<div class="btn">
<a href="{{url_for('business')}}">/
Negocio</a>
</div>
<div class="btn">
<a href="#">Instrucciones</a>
</div>
</div>
<div class="container_buttons_links_header_light_talk">
<div class="btn">
<a href="{{url_for('business.business_home')}}">/
Negocio</a>
</div>
<div class="btn">
<a href="#">Instrucciones</a>
</div>
</div>
Los enlaces al video de YouTube y la cuenta de GitHub para esta sección están abajo:
Toda la información de esta sección ha sido tomada de los siguientes enlaces:
Hay muchas formas de crear y validar formularios, he usado principalmente el enfoque seguido en los siguientes tres enlaces:
Los formularios web, como los campos de texto y las áreas de texto, permiten a los usuarios enviar datos a tu aplicación para usarlos en una acción o
para enviar grandes áreas de texto a la aplicación. En nuestra aplicación, estamos usando formularios para registrarse,
iniciar sesión e introducir frases a nuestra base de datos. En particular, usaremos WTForms, que es una biblioteca flexible de validación y renderización de formularios para el desarrollo web en Python.
En nuestra aplicación, vamos a crear un formulario de registro. En ese formulario de registro, los usuarios deben introducir su nombre de usuario, su correo electrónico y su contraseña. Dado que todos los usuarios deben tener estos tres campos, es una buena idea crear una clase. Una vez que un usuario introduce su nombre de usuario, correo electrónico y contraseña, se generará un objeto a partir de esa clase. Además, las clases que vamos a crear pueden usar métodos programados en flask que nos permiten detectar si los correos electrónicos son incorrectos, si los nombres de usuario no cumplen con ciertos requisitos, etcétera.
Si has configurado Flask.secret_key (o lo ha configurado desde SECRET_KEY),
puede usar sesiones en aplicaciones Flask. Una sesión hace posible recordar información de una solicitud a otra.
La forma en que Flask hace esto es mediante una cookie firmada.
El usuario puede ver el contenido de la sesión, pero no puede modificarlo a menos que conozca la clave secreta, por lo que asegúrate de que sea algo complejo e imposible de adivinar.
La clave secreta es útil para proteger nuestra aplicación de ataques de Cross Site Request Forgery. El Cross-Site Request Forgery (CSRF) es un ataque que obliga a los usuarios autenticados a enviar una solicitud a una aplicación web en la que están autenticados. Los ataques CSRF explotan la confianza que una aplicación web tiene en un usuario autenticado. (Por el contrario, los ataques de cross-site scripting (XSS) explotan la confianza que un usuario tiene en una aplicación web en particular). Un ataque CSRF explota una vulnerabilidad en una aplicación web si no puede diferenciar entre una solicitud generada por un usuario individual y una solicitud generada por un usuario sin su consentimiento.
Para obtener más información sobre sesiones, claves secretas y ataques de Cross Site Request Forgery, consulte:
Para crear WTForms, procedemos en tres pasos diferentes:
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired, Length, Email, EqualTo
class RegistrationForm(FlaskForm):
username = StringField('Nombre de usuario',
validators=[DataRequired(), Length(min=2, max=30)])
email = StringField('Correo electrónico',
validators=[DataRequired(), Email()])
password = PasswordField('Contraseña', validators=[DataRequired()])
confirm_password = PasswordField('Confirmar Contraseña',
validators=[DataRequired(), EqualTo('password')])
submit = SubmitField('Registrarse')
Para validar WTForms, procedemos en tres pasos diferentes:
from flask import render_template, Blueprint, redirect, flash, url_for
from capp.users.forms import RegistrationForm
users=Blueprint('users',__name__)
@users.route('/register', methods=['GET','POST'])
def register():
form = RegistrationForm()
if form.validate_on_submit():
return redirect(url_for('home.home_home'))
return render_template('users/register.html', title='register', form=form)
Los enlaces al video de YouTube y la cuenta de GitHub para esta sección están abajo:
En la sección anterior aprendimos cómo crear y validar un WTForm. En esta sección, aprenderemos cómo conectar el formulario con el archivo register.html donde el usuario puede completar el formulario de registro. Procedemos en diferentes pasos:
<form method="POST" action="">
{{ form.hidden_tag() }}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Únete hoy</legend>
<div class="form-group">
{{ form.username.label(class="form-control-label") }}
{{ form.username(class="form-control form-control-lg") }}
</div>
</form>
Los enlaces al video de YouTube y la cuenta de GitHub para esta sección están abajo:
Vamos a mostrar dos tipos de mensajes. Primero, en el archivo register.html, mostramos mensajes cuando el usuario introduce información que no cumple con los requisitos de validación introducidos en el archivo forms.py. Segundo, en el archivo home.html mostramos un mensaje cuando el usuario registra su información correctamente.
Mensajes en el archivo register.html. Usando Jinja, introducimos una sentencia if-else que nos ayuda a gestionar los mensajes de error.
Si el usuario introduce alguna información en el campo de nombre de usuario que viola los requisitos de validación introducidos en el archivo forms.py, recopilamos esos errores y los mostramos dentro de un contenedor con la clase de bootstrap “invalid-feedback”. De lo contrario, no mostramos ningún mensaje de error.
Mensajes en el archivo home.html. Usando Jinja, introducimos una sentencia with, una if y una for statement en nuestro archivo home.html para mostrar información al usuario cuando se registra en la aplicación.
En esas sentencias, tomamos los mensajes flash de la ruta y los mostramos teniendo en cuenta la categoría del mensaje y creando un bootstrap específico dependiendo de la categoría del mensaje.
<div class="form-group">
{{ form.username.label(class="form-control-label") }}
{% if form.username.errors %}
{{ form.username(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.username.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.username(class="form-control form-control-lg") }}
{% endif %}
</div>
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
<div class="alert alert-{{ category }}">
{{ message }}
</div>
{% endfor %}
{% endif %}
{% endwith %}
Los enlaces al video de YouTube y a la cuenta de GitHub para esta sección están a continuación:
GitHub es una plataforma de desarrollo de software en línea. Se utiliza para almacenar, rastrear y colaborar en proyectos de software. Facilita a los desarrolladores compartir archivos de código y colaborar con otros desarrolladores en proyectos de código abierto. Se puede encontrar información útil para saber más sobre GitHub en los siguientes enlaces:
En esta sección, creamos una cuenta de GitHub; aprendemos a editar el archivo readme.md; creamos un repositorio y agregamos carpetas y archivos; editamos archivos y carpetas y hacemos commit de los cambios; creamos ramas y fusionamos ramas; aprendemos a deshacer un commit.
Explicaré las bases de estos puntos en esta sección, pero la mejor manera de abordarlos es viendo el video de YouTube para esta sección,
seguir los pasos y hacerlos vosotros mismos.
Todas las cosas que haremos en esta sección se pueden hacer utilizando la línea de comandos (comando git).
Esa es una forma eficiente de trabajar entre Visual Studio Code, GitHub y el servidor.
Sin embargo, he decidido hacer todos los pasos en esta sección utilizando la interfaz gráfica de usuario en GitHub y usando GitHub Desktop.
Por favor, descarga e instala GitHub Desktop en tu ordenador (el proceso es muy similar para Windows y Mac).
El objetivo de este curso es centrarse en aprender a programar una aplicación utilizando diferentes lenguajes de programación. No quiero que también tengas que aprender a usar el comando git para interactuar con GitHub. Eso está fuera del alcance de este curso. En el futuro, desarrollaré algunos videos y contenido específico para explicar eso. Tres buenos puntos de partida para aprender a usar el comando git se pueden encontrar aquí:
# El encabezado más grande
## El segundo encabezado más grande
###### El encabezado más pequeño
**Este es un texto en negrita**
*Este texto está en cursiva*
~~Este fue un texto erróneo~~
<sub>Este es un texto en subíndice</sub>
- George Washington
* John Adams
+ Thomas Jefferson
1. James Madison
2. James Monroe
3. John Quincy Adams
Los enlaces al video de YouTube y a la cuenta de GitHub para esta sección están a continuación:
AWS (Amazon Web Services) es una plataforma de computación en la nube integral y en evolución proporcionada por Amazon que incluye una combinación de ofertas de infraestructura como servicio (IaaS), plataforma como servicio (PaaS) y software como servicio (SaaS). Los servicios de AWS pueden ofrecer a una organización herramientas como potencia de cálculo, almacenamiento de bases de datos y servicios de entrega de contenido.
AWS ofrece más de 200 servicios completos desde centros de datos a nivel mundial.
Esos servicios incluyen almacenamiento, bases de datos, inteligencia artificial, balanceo de carga,
escalabilidad, etcétera. La versatilidad y flexibilidad de AWS ayudan a personalizar y escalar tu proyecto de manera fácil y económica. En el video en el que explico cómo crear usuarios y grupos, explico algunas de las características que usaremos durante el curso. Alguna información útil sobre AWS se puede encontrar en los siguientes enlaces:
Crear una cuenta en AWS es sencillo siguiendo el enlace a continuación. Es necesario introducir una tarjeta de crédito, aunque vamos a utilizar la versión Free Tier de AWS durante la mayor parte del curso. Al finalizar el curso, puedes eliminar tu cuenta, ya que tu aplicación se ejecutará en Forward y no necesitarás pagar por el servidor y sus servicios.
AWS Identity and Access Management (IAM) es un servicio web que te ayuda a controlar de forma segura el acceso a los recursos de AWS. Con IAM, podemos gestionar centralmente los permisos que controlan a qué recursos de AWS pueden acceder los usuarios. Usamos IAM para controlar quién está autenticado (ha iniciado sesión) y autorizado (tiene permisos) para usar recursos.
Cuando creamos una cuenta de AWS, comenzamos con una identidad de inicio de sesión que tiene acceso completo a todos los servicios y recursos de AWS en la cuenta. Esta identidad se llama el usuario raíz de la cuenta de AWS y se accede iniciando sesión con la dirección de correo electrónico y la contraseña que usamos para crear la cuenta. AWS recomienda encarecidamente no utilizar el usuario raíz para tareas cotidianas. Protege tus credenciales de usuario raíz y úsalas solo para realizar las tareas que solo el usuario raíz puede realizar. Esa es la razón por la que crear usuarios y grupos utilizando IAM es extremadamente útil.
En el video de YouTube para esta sección, explico cómo crear grupos, usuarios y cómo agregar usuarios a un grupo. Esto será muy útil para nuestro proyecto, ya que cada miembro del grupo puede usar AWS sin comprometer la seguridad de la cuenta raíz.
Algunos enlaces útiles para esa sección se pueden encontrar en los siguientes enlaces:
Elastic Beanstalk es un servicio para desplegar y escalar aplicaciones web y servicios. Carga tu código y Elastic Beanstalk maneja automáticamente el despliegue, desde la provisión de capacidad, balanceo de carga y autoescalado hasta la supervisión de la salud de la aplicación.
Cuando usamos Elastic Beanstalk, creamos un entorno en el cual tenemos acceso a muchos servicios de AWS como EC2, S3, Simple Notification Service (SNS), CloudWatch, autoescalado y Elastic Load Balancers. Esta característica de Elastic Beanstalk facilita el despliegue de nuestra aplicación y nos ayuda a escalar nuestro proyecto de manera fácil y económica.
Algunos enlaces útiles para esa sección se pueden encontrar en los siguientes enlaces:
AWS CodePipeline es un servicio de entrega continua totalmente gestionado que te ayuda a automatizar tus pipelines de lanzamiento para actualizaciones rápidas y confiables de aplicaciones e infraestructuras.
AWS CodePipeline nos ayuda a conectar nuestro repositorio de GitHub con nuestro Elastic Beanstalk de manera muy eficiente. Así, cuando introducimos algunos cambios en nuestro código y hacemos commit de esos cambios en GitHub, podemos desplegar esos cambios fácilmente en el servidor usando CodePipeline.
Algunos enlaces útiles para esa sección se pueden encontrar en los siguientes enlaces:
El enlace al video de YouTube está a continuación:
Para desplegar nuestra aplicación en AWS, necesitamos considerar dos cosas:
¿Qué son las variables de entorno?
Las variables de entorno son valores predeterminados que generalmente se utilizan para proporcionar la capacidad de
configurar un valor en tu código desde fuera de tu aplicación.
¿Cómo puedo mantener seguros estos archivos?
Por ejemplo, las claves de AWS son un recurso valioso. Existen bots cuyo único propósito es tratar de escanear GitHub en busca de claves. Si alguien encuentra una clave de AWS, podría usarla para acceder a recursos, como ejecutar una operación de minería de bitcoins a tu costa. Esto no es para asustarte, es para que estés consciente y evites que tus claves sean comprometidas.
La información sobre variables de entorno ha sido tomada del siguiente enlace:
En este desafío semanal, debes hacer cuatro cosas diferentes.
Primero, usando Blueprints, debes crear un nuevo paquete llamado usuarios. Dentro de ese paquete, crea dos funciones diferentes: una para registrar usuarios y otra para ayudar a los usuarios a iniciar sesión. En este capítulo, vamos a crear solo dos funciones simples para renderizar dos archivos HTML: register.html y login.html. Estos dos archivos HTML estarán en una carpeta llamada usuarios dentro de la carpeta templates.
Para utilizar las dos funciones en el paquete usuarios, modificamos la barra de navegación en layout.html para introducir dos nuevos enlaces. Además, en el archivo home.html, tenemos dos botones para registrar e iniciar sesión. También necesitamos dos enlaces para esos dos botones a las dos funciones en el paquete usuarios.
Segundo, usando Blueprints, debemos crear dos funciones dentro del paquete light_talk_app.
Estas dos funciones nos darán la oportunidad de añadir frases
y también nos permitirán acceder a las frases que estarán en nuestras bases de datos.
Colocamos esos dos archivos, y el archivo light_talk_app.html en una carpeta dentro de la carpeta templates llamada light_talk_app.
En el archivo light_talk_app.html, debemos conectar nuestros botones a las dos funciones creadas en el paquete light_talk_app.
Tercero, usando los formularios que hemos estudiado en este capítulo, creamos un formulario para registrarse y para hacer el login.
Cuarto, desplegamos nuestra app en AWS.
Discutiremos el desafío semanal el viernes .... Usaremos el chat principal para ayudarnos mutuamente en el desafío semanal. Dentro de esos días, por favor comparte la información que consideres relevante para ayudar a los otros grupos.