Anteriormente. Apéndice 20. Uso de MYSQL o MARIADB en un proyecto Flask.
En este capítulo vamos a desplegar nuestra aplicación en Heroku, que es un servidor de alojamiento en la nube externo. Muchos proveedores de alojamiento en la nube ofrecen una plataforma administrativa en la que se pueden ejecutar aplicaciones.
Todo lo que necesitamos para implementar una aplicación de Python en estas plataformas es la aplicación solamente, porque el hardware, el sistema operativo, los interpretes de lenguaje de secuencias de comandos, las bases de datos etc son todos administrados por el servicio. Este tipo de servicio se denomina Plataforma como servicio o PaaS.
Heroku, que es un servicio muy popular, nos facilita además una serie de servicios de forma gratuita en donde podremos implementar nuestra aplicación de Python.
Hosting en Heroku.
La implementación de una aplicación Python en Heroku se realiza a través de la herramienta de control de versiones de git, por lo que deberemos tener nuestra aplicación en un repositorio de git. Heroku busca un archivo llamado Procfile en el directorio raíz de la aplicación para obtener instrucciones sobre como iniciar la aplicación. Para los archivos de Python, Heroku también espera un archivo llamado "requirements.txt" que contendrá todas las dependencias del modulo que deben instalarse. Una vez que nuestra aplicación se cargue en los servidores de Heroku a través de git, solamente tendremos que esperar unos segundos hasta que la aplicación este en línea y funcionando. Así de simple.
Lógicamente al ser un servicio gratuito, que nos facilitan para desarrollar y practicar la programación, la capacidad de computo y almacenamiento es limitada. Si necesitas mayor potencia tendrás que adquirirla a través de lo que Heroku llama "dynos". Pero para lo básico y para practicar, el servicio gratuito nos servirá de sobra.
Crear una cuenta en Heroku.
Antes de poder empezar, lógicamente tenemos que tener una cuenta con ellos. Visita www.heroku.com y crea una cuenta gratuita.
Instalando el cliente de Heroku en el ordenador.
$sudo snap install --classic heroku
$ heroku login
Preparando la aplicación para subirla a Heroku.
$ mkdir proyecto
$ cd proyecto
proyecto $
2.- Creo en el entorno virtual que usará la aplicación:
proyecto $ python3 -m venv venv
proyecto $ mkdir src
Dentro de esta carpeta colocaré los archivos del programa de Flask que hemos utilizado a lo largo de este tutorial y que puedes encontrar en esta carpeta del proyecto en github..
Para descargar solamente este directorio y no todo el repositorio, entras en el directorio POST 19, copias el enlace del navegador y puedes utilizar alguno de estos 2 links que te dejo:
https://downgit.github.io/#/home
https://download-directory.github.io/
para obtener un archivo zip con el código fuente. Luego extraes los archivos dentro de la carpeta src.
La carpeta src debería quedar tal como se ve a continuación.
requirements.txt => Este archivo contiene todas las librerías o bibliotecas de Python que el programa utiliza y que son necesarias para su funcionamiento. Todos los paquetes que utilices para el proyecto deben estar aquí para que heroku sepa lo que se necesita. Este archivo en su día lo realizamos entrando en el entorno virtual y ejecutando la siguiente instrucción:
env $ pip freeze > requirements.txt
Aquí ya esta hecho y si lo abres verás todas las bibliotecas que se utilizan en el programa.
Nota: Si en alguna ocasión te sale dentro de requirements.txt el paquete
pkg-resources==0.0.0 elimínalo que luego al subirlo a heroku da un error.
Como lo voy a necesitar posteriormente para pasar de una base sqlite a una postgresql (un poco más adelante veras porqué) vamos a instalar todos los paquetes o dependencias del proyecto en local. Para instalarlos en nuestro ordenador tenemos que entrar en el entorno virtual, en el directorio src que contiene requirements.txt y ejecutar la siguiente instrucción. Vamos a hacerlo:
env $ pip install -r requirements.txt
[runtime.txt] => Es un archivo en el que se recoge la versión de Python del programa. Este es un archivo opcional y sino lo creamos el programa se ejecutará con la versión 3.9.5. No obstante podemos elegir otra versión distinta. Mira el manual ya que hay que escribir en el archivo la versión de una forma particular y con los tres dígitos, ya que sino no funcionará. Para saber que versión de Python estamos tenemos simplemente tecleamos:
>>> python3 --version
Python 3.8.5
Procfile => En este fichero se recoge que archivo se debe ejecutar en Heroku cuando la aplicación se inicie.
En Heroku se necesita para que cualquier proyecto de Flask funcione instalar el complemento gunicorn que ejecuta el servidor http. Como este paquete en el proyecto no estaba instalado necesitamos hacerlo. Para ello entraremos en el entorno virtual (desde el directorio src, $ source ../venv/bin/activate) y ejecutaremos la siguiente instrucción:
(env) /proyecto/src $ pip install gunicorn
Luego creamos el archivo Procfile y escribimos:
web: flask db upgrade; gunicorn inicio:app
Guardamos y salimos.
inicio es el nombre del archivo de python que ejecuta la aplicación (inicio.py) y app hace referencia al módelo que lanza la aplicación dentro del mismo (app = Flask(__name__)). "flask db upgrade" lo utilizaremos para consolidar la migración de nuestra base de datos sql a la que utiliza heroku como veremos más adelante en el capitulo.
Como esta biblioteca no estaba instalada en su día, en el archivo requirements.txt tenemos que añadirla. Para ver la versión que se nos ha instalado tecleamos:
(env) ~/proyecto/src $ pip freeze
gunicorn==20.1.0
Pues tal cual copiamos la salida "gunicorn==20.1.0" y la añadimos al final del archivo requirements.txt.
Es sistema de archivos es temporal.
Afortunadamente lo que si nos proporciona Heroku, con un complemento, es
una base de datos propia Postgresql lo que nos solucionará el problema de
la persistencia de los datos.
Trabajando con la base de datos Postgresql de Heroku.
$ heroku create nombre_proyecto_heroku
$ heroku addons:create heroku-postgresql:hobby-dev --app novatillo
Creating heroku-postgresql:hobby-dev on ⬢ novatillo... free
Database has been created and is available
! This database is empty. If upgrading, you can transfer
! data from another database with pg:copy
Created postgresql-cylindrical-56001 as DATABASE_URL
Use heroku addons:docs heroku-postgresql to view documentation
La url de la base de datos se almacena en heroku en una variable de entorno llamada DATABASE_URL que estará disponible cuando se ejecute la aplicación. Pero aun que ya tenemos la base de datos tenemos que adaptar el conector en nuestro programa para poder usarla.
Conectando la base de datos de Heroku a nuestra aplicación Python.
Para usar PostgreSQL como nuestra base de datos en una aplicación de Python lo primero que tenemos que hacer es instalar el paquete psycopg2 en el entorno virtual, que es como el driver para que sqlalchemy pueda relacionarse con la la base postgrepsql que utiliza heroku:
(venv) ~/proyecto/src $ pip install psycopg2-binary
y como es un paquete nuevo que también es necesario para que nos funcione el proyecto en heroku tenemos que añadirlo al final del archivo requirements.txt
Ahora lo que tenemos que hacer es modificar el conector en nuestro programa para que SQLAlchemy se pueda comunicar con la base de datos de heroku una vez que lo hayamos subido a su servidor . Este conector es una variable del sistema llamada DATABASE_URL por lo que tenemos que capturarla y usarla en nuestro código tal como dice el manual de Heroku.
Para saber cual es el conector con la base de datos de heroku podemos hacerlo desde la pagina web de administración de proyectos de heroku o desde el terminal usando la siguiente instrucción:
heroku config:get DATABASE_URL -a nombre_aplicación
# Como mi aplicación se llama novatillo (venv) ~/proyecto/scr $ heroku config:get DATABASE_URL -a novatillo
Ahora tendríamos que entrar en config.py dentro de la carpeta config y modificar la línea 17 para capturar la variable de entorno en donde esta la base de datos en Heroku. Le tendríamos que decir al programa, que el conector se encuentra primero en la variable del sistema DATABASE_URL y si no es así que use la antigua de sqlite.
Sin embargo por la nota siguiente voy a usar la uri que acabamos de copiar, y la pegaremos directamente. Ya que es un string la pegaremos dentro de un par de comillas " ". Como ves la cadena comienza por "postgres:// ", pues bien cambia la palabra "postgres" por "postgresql". Quedarías así:
¿Por qué? Lee lo siguiente:
Nota importante a la fecha en la que estoy escribiendo esto.
sqlalchemy.exc.NoSuchModuleError: Can't load plugin: sqlalchemy.dialects:postgres
Empezamos instalando el paquete flask-migrate en nuestro entorno virtual:
(venv) ~/proyecto/src $ pip install flask-migrate
y añadimos el paquete al archivo requirements.txt (Flask-Migrate==3.0.1)
Ahora en el archivo principal de la aplicación inicio.py tenemos que importar Migrate desde flask_migrate:
y declararla después de db=SQLAlchemy(app)
(venv) ~/proyecto/src $ export FLASK_APP=inicio.py
(venv) ~/proyecto/src $ flask db init
y realizamos la primera migración:
(venv) ~/proyecto/src $ flask db migrate -m "preparando para heroku"
Si te fijas dentro del directorio src que tenemos en local se ha creado un nuevo directorio llamado "migrations".
web: flask db upgrade; gunicorn inicio:app
Creación del repositorio git, configuración y subida del proyecto a heroku.
$ sudo apt-get install git
$ git config --global user.name "nombre_usuario"
$ git config --global user.email tucorreo@correo.com
Si quieres ver tu configuración puedes usar la siguiente orden en el terminal:
git config --list
2) Nos metemos en la carpeta src, si no lo estamos ya y tecleamos. No hace falta estar dentro del entorno virtual pero si es importante estar en la carpeta src.
$ git init
Inicia el repositorio.
$ git status
Vemos los archivos preparados para subir (en rojo)
$ git add .
Le decimos a git que añada todo lo que hay en el directorio en el que estamos (src) al repositorio.
$ git commit -m "paquete git para subir a heroku"
y con esto creamos el repositorio. Si te fijas se ha creado un directorio llamado .git oculto dentro del directorio src. Ahí esta el repositorio. Si más adelante quieres borrar el repositorio solo tienes que borrarlo.
Ahora enlazamos la aplicación que hemos creado en Heroku (novatillo en mi caso) con la aplicación o repositorio de flask que tenemos en el ordenador.
# heroku git:remote nombre_aplicación
$ heroku git:remote novatillo
Todo esto lo hacemos dentro de la carpeta src.
Ahora que tenemos el proyecto enlazado lo subimos a heroku (¡por fin!)
$ git push heroku master
y si todo va bien, comprimirá la aplicación, subirá los archivos, instalará los paquetes y ya tendremos la aplicación subida y el link de nuestra aplicación en Heroku:
Pero antes de acceder y como el primero de los dos subcomandos que usamos en el archivo Procfile
Procfile: Heroku Procfile.
web: flask db upgrade; gunicorn inicio:app
está basado en un comando de flask, al igual que hicimos cuando iniciamos la migración en local, necesitamos añadir la variable FLASK_APP al entorno de Heroku
$ heroku config:set FLASK_APP=inicio.py
y ya esta todo.
Si navegamos a la página que nos ha facilitado heroku https://(nombre_proyecto).herokuapp.com veremos nuestro proyecto funcionando en el servidor:
Anexo.
Otros comandos de heroku cli que nos pueden ser útiles son:
Establecer una variable de entorno en Heroku
$ heroku config:set FLASK_APP=inicio.py
Ejecutar un comando en la consola de la aplicación en heroku. En este caso una que nos muestre el historial de
migraciones
# heroku run -a nombre_aplicación (orden a ejecutar)
$ heroku run -a novatillo flask db history
Podríamos haber hecho el upgrade de la migración no poniendo el comando automáticamente en el archivo Procfiles sino usando la consola de esta forma:
Upgrade de la migración
$ heroku run -a novatillo flask db upgrade
Próximo Capítulo. Flask 22. Desplegar una aplicación de Flask en un contenedor de Docker.
No hay comentarios:
Publicar un comentario