Diferencia entre revisiones de «Flask»

De Jose Castillo Aliaga
Ir a la navegación Ir a la búsqueda
Línea 106: Línea 106:
  $  
  $  
</pre>
</pre>
El codi per a connectar de forma mínima és:


== Hola Mon ==
== Hola Mon ==

Revisión del 16:21 10 jun 2021

De moment, açò no és un manual ni tutorial de flask. És una col·lecció d'aclaracions sobre el Manual Oficial per a projectes propis o en classe.

Instal·lació

En ubuntu 20.04 ja venen instal·lats quasi tots els paquets necessaris inicialment. Cal instal·lar python3-venv.

La configuració d'una aplicació feta en Flask és molt diversa. Aquestes són algunes de les opcions:

  • Executar Flask sobre el fitxer de l'aplicació i accedir al port que obri. Flask té el seu propi WSGI fet en Werkzeug, així que funcionarà. No obstant, no el recomanen perquè no està optimitzat per a entrar en producció. Tant per rendiment (Un sol fil d'execució, difícultat amb varis accessos simultanis) com per la seguretat (HTTPS i altres)
  • Utilitzar un WSGI com uWSGI o Gunicorn. Aquests sí estan preparats per a entrar en producció. Saben distribuir la càrrega i solucionen problemes de rendiment.
  • Utilitzar Nginx/Apache amb un mòdul per WSGI i cridar a Flask: Aquests actuen com a proxy invers, millorant considerablement el rendiment i la seguretat (HTTPS). Amés, permeten tindre contingut estàtic amb millor rendiment.
  • Utilitzar Nginx/Apache, connectat a uWSGI o Gunicorn, que executa Flask: És l'opció més complexa per configurar, però la ideal per a un entorn de producció complex. La capa enmig del WSGI simplifica les cridades a l'aplicació i millora el rendiment.Tutorial

Una vegada decidit quina configuració anem a triar, cal preguntar-se si volem un entorn virtual de Python per a la nostra aplicació. Això independitza l'aplicació, el Python i les biblioteques que utilitzem de la resta del sistema. En entorns en els que es van a implementar varies aplicacions Python és recomanable.

python3.6 -m venv myprojectenv
source myprojectenv/bin/activate
pip install gunicorn flask


Configuració mínima

En aquest exemple, anem a fer una configuració mínima funcional. Es farà amb Nginx <-> Flask per les següents raons:

  • Es tracta d'un exemple real en el que una Raspberry Pi ha de fer de servidor en una xarxa local.
  • Al no donar servei a Internet i tindre pocs clients simultanis no és necessari preocupar-se tant del rendiment o seguretat.
  • Necessitem en Nginx per a donar accés a fitxers estàtics, ja que la web que proporcionarà serà principalment una SPA. Aquesta aplicació accedirà a l'aplicació feta en Flask, la qual proporcionarà una API REST.
  • L'aplicació necessitarà una base de dades. Aquesta serà Mariadb, podem instal·lar PHPMyAdmin per gestionar-la. Però no està en els repositoris de Debian, així que optarem per DBeaver.
  • Es decideix fer-la en Python perquè necessitem accedir als pins GPIO i amb Python és senzill.

En el sistema operatiu de la Raspberry (basat en Debian) farem les següents instal·lacions i configuracions:

 $ mkdir projecte
 $ cd projecte
 ~/projecte $ python3 -m venv venv
 ~/projecte $ . venv/bin/activate
 (venv) ~/projecte $ pip install flask

Fins a aquest moment, tenim una directori per al projecte, un entorn virtual i dins hem instal·lat Flask.

Ara anem a crear un servei en systemd per arrancar l'entorn virtual en arrancar el sistema. Per tant, en: /etc/systemd/system/projecte.service

[Unit]
Description=Flask myproject
After=network.target

[Service]
User=pi
Group=www-data
WorkingDirectory=/home/pi/projecte
Environment="PATH=/home/pi/projecte/venv/bin"
ExecStart=/home/pi/projecte/venv/bin/flask run --host=0.0.0.0

[Install]
WantedBy=multi-user.target

I podem gestionar el servei en:

 $ systemtctl [start,stop,restart] projecte.service 

Això farà que arranque en el port 5000 al qual tenim que redireccionar en Nginx. Per a fer això, anem a afegir una ruta per a l'app en Nginx a la que apliquem un proxy invers i la ruta normal quedarà per a les dades estàtiques:

         location / {
		# First attempt to serve request as file, then
		# as directory, then fall back to displaying a 404.
		try_files $uri $uri/ =404;
	}

	location /projecte/ {
	       include proxy_params;
               proxy_pass http://127.0.0.1:5000$request_uri;
	}

Connexió amb Mariadb

En aquest cas, anem a instal·lar Mariadb. Després connectarem Flask amb la base de dades.

 $ sudo apt install mariadb-server mariadb-client
 $ sudo mysql_secure_installation

La base de dades la anem a fer de la forma tradicional, sols que per comoditat, la podem gestionar amb una interfície gràfica. Un bon programa per a fer això és PHPMyAdmin. Un altre, sense necessitat de tindre un servei més ni PHP instal·lat, és DBeaver en un altre ordinador amb GUI.

Anem a configurar per poder entrar en remot com diu aquest manual

En el nostre cas, sols cal comentar aquesta línia:

 #bind-address = <some ip-address>

També li donem accés a root en qualsevol IP (Açò és un greu problema de seguretat i sols ha de fer-se per a fer proves.)

GRANT ALL PRIVILEGES ON *.* TO 'root'@'%'    IDENTIFIED BY '1234' WITH GRANT OPTION;

En el client de bases de dades preferit creem una base de dades i una taula. En el meu cas la base de dades és pro i la taula programes.

Ara anem a connectar Flask amb Mariadb.

 $ sudo apt-get install libmariadbclient-dev
 $ 

El codi per a connectar de forma mínima és:

Hola Mon

from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello_world():
    return "<p>Hola Mon</p>"

Com es veu, importem la classe Flask i creem un objecte app al que li passem el __name__ que és el nom del mòdul. El més interessant és el decorador @app.route() que indica la funció que s'executarà per a respondre a la ruta indicada. El que retorna és un HTML.

Per a executar-la necessitem declarar una variable amb export per a que flask conega el nom de l'aplicació:

 $ export FLASK_APP=hello
 $ flask run --host=0.0.0.0

Li posem el --host=0.0.0.0 per a que es puga accedir de fora de la Raspbery per fer proves.

Si volem veure els possibles errors:

 $ export FLASK_ENV=development

Gràcies al WSGI de Werkzeug, podem passar paràmetres en la ruta, per exemple:

from flask import Flask
from markupsafe import escape

app = Flask(__name__)

@app.route("/<name>")
def hello(name):
    return f"Hello, {escape(name)}!"

Això serà molt útil per a fer el API REST.