Diferencia entre revisiones de «Flask»

De Jose Castillo Aliaga
Ir a la navegación Ir a la búsqueda
Línea 38: Línea 38:
Fins a aquest moment, tenim una directori per al projecte, un entorn virtual i dins hem instal·lat 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'''
<pre>
[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
</pre>
I podem gestionar el servei en:
<pre>
$ systemtctl [start,stop,restart] projecte.service
</pre>
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:
<pre>
        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;
}
</pre>


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

Revisión del 23:00 7 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.

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, instal·larem PHPMyAdmin per gestionar-la.
  • 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
 ~/rpojecte $ python3 -m venv venv
 (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;
	}

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.