Difference between revisions of "Flask"
m (→templates=) |
|||
(15 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
− | = | + | =Basics= |
− | https://flask.palletsprojects.com/en/1.1.x/quickstart/ | + | Check this[https://flask.palletsprojects.com/en/1.1.x/quickstart/] |
+ | |||
+ | Hello world app: | ||
+ | <syntaxhighlight lang=python> | ||
+ | #!/usr/bin/env python3 | ||
+ | |||
+ | from flask import Flask | ||
+ | print(__name__) | ||
+ | app = Flask(__name__) | ||
+ | |||
+ | @app.route('/') | ||
+ | |||
+ | def welcome(): | ||
+ | return 'Welcome' | ||
+ | |||
+ | if __name__ == '__main__': # When executed on the commandline (build in webserver) | ||
+ | app.run(host='0.0.0.0',port=5000) # Listen to localhost port 5000, you can also use flask run for options | ||
+ | #app.run(host='0.0.0.0',port=8080,Debug=True) # Run in debug mode, listen to all hosts on port 8080 | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | Run the build-in server listening to all | ||
+ | <syntaxhighlight lang=bash> | ||
+ | export FLASK_APP=welcome_app.py | ||
+ | flask run --host=0.0.0.0 | ||
+ | </syntaxhighlight> | ||
+ | welcome_app | ||
+ | * Serving Flask app "welcome_app" | ||
+ | * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit) | ||
+ | |||
+ | Now you can browse to <serverIP>:5000 | ||
https://code.tutsplus.com/tutorials/creating-a-web-app-from-scratch-using-python-flask-and-mysql--cms-22972 | https://code.tutsplus.com/tutorials/creating-a-web-app-from-scratch-using-python-flask-and-mysql--cms-22972 | ||
+ | =Integrate with nginx= | ||
+ | |||
+ | Mayor part is from this site [https://vladikk.com/2013/09/12/serving-flask-with-nginx-on-ubuntu/]. | ||
+ | |||
+ | * Install uwgi-emperor and it's python plugin | ||
+ | Configuration files I used. | ||
− | = | + | :* Generic configuration file (/etc/uwsgi-emperor/emperor.ini): |
+ | [uwsgi] | ||
+ | # try to autoload appropriate plugin if "unknown" option has been specified | ||
+ | autoload = true | ||
+ | # enable master process manager | ||
+ | master = true | ||
+ | # spawn 2 uWSGI emperor worker processes | ||
+ | workers = 2 | ||
+ | # automatically kill workers on master's death | ||
+ | no-orphans = true | ||
+ | # place timestamps into log | ||
+ | log-date = true | ||
+ | # user identifier of uWSGI processes (same as who runs the web-server) | ||
+ | uid = www-data | ||
+ | # group identifier of uWSGI processes (same as who runs the web-server) | ||
+ | gid = www-data | ||
+ | # vassals directory | ||
+ | emperor = /etc/uwsgi-emperor/vassals | ||
+ | plugins = python3 | ||
+ | |||
+ | :* Application configuration file (/etc/uwsgi-emperor/vassals/welcome.ini) | ||
+ | |||
+ | [uwsgi] | ||
+ | #application's base folder | ||
+ | base = /var/www/flask | ||
+ | #python module to import | ||
+ | app = welcome | ||
+ | module = %(app) | ||
+ | pythonpath = %(base) | ||
+ | #socket file's location | ||
+ | socket = /var/local/uwsgi/%n.sock | ||
+ | #permissions for the socket file | ||
+ | chmod-socket = 664 | ||
+ | #the variable that holds a flask application inside the module imported at line #6 | ||
+ | callable = app | ||
+ | #location of log files | ||
+ | logto = /var/log/uwsgi/%n.log | ||
+ | plugins = python3 | ||
+ | |||
+ | * Create a virtual webserver (port 80 is save enough if you have a secure front-end server) | ||
+ | |||
+ | <syntaxhighlight lang="nginx"> | ||
+ | server { | ||
+ | listen 80 ; | ||
+ | listen [::]:80 ; | ||
+ | |||
+ | root /var/www/flask; | ||
+ | |||
+ | server_name <fqdn>; | ||
+ | |||
+ | location / { | ||
+ | include uwsgi_params; | ||
+ | uwsgi_pass unix:/var/local/uwsgi/welcome.sock; | ||
+ | } | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | =Generate web pages= | ||
https://flask.palletsprojects.com/en/1.1.x/patterns/templateinheritance/#template-inheritance | https://flask.palletsprojects.com/en/1.1.x/patterns/templateinheritance/#template-inheritance | ||
− | = | + | |
+ | [https://www.idkrtm.com/creating-a-webpage-using-python-and-flask/ Source for this basic app] | ||
+ | |||
+ | Put a index.html in <app-base>/templates/ | ||
+ | |||
+ | <syntaxhighlight lang=python> | ||
+ | #!/usr/bin/env python3 | ||
+ | |||
+ | from flask import Flask, render_template | ||
+ | |||
+ | print(__name__) | ||
+ | app = Flask(__name__) | ||
+ | |||
+ | @app.route('/html') | ||
+ | def static_page(): | ||
+ | return render_template('index.html') | ||
+ | |||
+ | if __name__ == '__main__': | ||
+ | app.run(host='0.0.0.0',port=5000,debug=True) | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | |||
+ | =Microservices and/or more applications on 1 web-server= | ||
+ | |||
+ | Starting with [https://jawher.me/multiple-python-apps-with-nginx-uwsgi-emperor-upstart/ this page] and additional a lot more we got it working on [https://www.raspberrypi.org/software/ raspberry pi debian]. | ||
+ | |||
+ | # Make python3 the default<br><code>cd /usr/bin;rm python;ln -s python3 python</code> | ||
+ | # Install uwsgi and python plugin<br><code>apt install uwsgi uwsgi-plugin-python3</code> | ||
+ | # install nginx<br><code>apt install nginx-full</code> | ||
+ | I had to make a small change in the nginx configuration;<br> | ||
+ | <code>vi /etc/nginx/conf.d/my.conf<br> | ||
+ | server_names_hash_bucket_size 64; | ||
+ | </code> | ||
+ | |||
+ | ===Super simple apps=== | ||
+ | In /var/www/flask/app1/app1/py | ||
+ | <syntaxhighlight lang=python> | ||
+ | #!/usr/bin/env python3 | ||
+ | |||
+ | from flask import Flask | ||
+ | import os | ||
+ | |||
+ | application = Flask(__name__) | ||
+ | |||
+ | @application.route('/app1') | ||
+ | def app1(): | ||
+ | return "App 1 live and kicking" | ||
+ | |||
+ | if __name__ == '__main__': | ||
+ | application.run(host='0.0.0.0', port=8080,debug=True) | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | /var/www/flask/app2/app2.py | ||
+ | <syntaxhighlight lang=python> | ||
+ | #!/usr/bin/env python3 | ||
+ | |||
+ | from flask import Flask | ||
+ | import os | ||
+ | |||
+ | application = Flask(__name__) | ||
+ | |||
+ | @application.route('/app2') | ||
+ | def app2(): | ||
+ | return "App 2 live and kicking" | ||
+ | |||
+ | if __name__ == '__main__': | ||
+ | application.run(host='0.0.0.0', port=8080,debug=True) | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ===uwsgi configuration=== | ||
+ | |||
+ | /etc/uwsgi/apps-available/emperor.xml | ||
+ | <syntaxhighlight lang=xml> | ||
+ | <uwsgi> | ||
+ | <autoload>true</autoload> | ||
+ | <no-orphan>true</no-orphan> | ||
+ | <emperor>/etc/uwsgi/vassals-enabled</emperor> | ||
+ | <master>true</master> | ||
+ | <emperor-nofollow>true</emperor-nofollow> | ||
+ | <processes>1</processes> | ||
+ | <uid>www-data</uid> | ||
+ | <gid>www-data</gid> | ||
+ | </uwsgi> | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | /etc/uwsgi/apps-available/apps.xml | ||
+ | <syntaxhighlight lang=xml> | ||
+ | <uwsgi> | ||
+ | <plugins>python3</plugins> | ||
+ | <master>false</master> | ||
+ | <processes>1</processes> | ||
+ | <vaccum>true</vaccum> | ||
+ | <chmod-socket>666</chmod-socket> | ||
+ | <socket>/tmp/%n.sock</socket> | ||
+ | <uid>www-data</uid> | ||
+ | <gid>www-data</gid> | ||
+ | <pythonpath>/var/www/flask/%n</pythonpath> | ||
+ | <module>%n</module> | ||
+ | </uwsgi> | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Make them available | ||
+ | <syntaxhighlight lang=bash> | ||
+ | cd /etc/uwsgi/apps-enabled | ||
+ | ln -s ../apps-available/emperror.xml | ||
+ | cd /etc/uwsgi/vassals-enabled | ||
+ | ln -s ../apps-available/apps.xml app1.xml | ||
+ | ln -s ../apps-available/apps.xml app2.xml | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ===Create a nginx virtual host=== | ||
+ | |||
+ | /etc/nginx/sites-enabled/apps.conf | ||
+ | |||
+ | <syntaxhighlight lang=nginx> | ||
+ | server { | ||
+ | listen 80; | ||
+ | server_name <your webserver fdqn>; | ||
+ | index index.html; | ||
+ | |||
+ | root /var/www/flask; | ||
+ | |||
+ | location /app1 { | ||
+ | include uwsgi_params; | ||
+ | uwsgi_param SCRIPT_NAME /app1; | ||
+ | uwsgi_modifier1 30; | ||
+ | uwsgi_pass unix://tmp/app1.sock; | ||
+ | } | ||
+ | |||
+ | location /app2 { | ||
+ | include uwsgi_params; | ||
+ | uwsgi_param SCRIPT_NAME /app2; | ||
+ | uwsgi_modifier1 30; | ||
+ | uwsgi_pass unix://tmp/app2.sock; | ||
+ | } | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ===Start things=== | ||
+ | service uwsgi start | ||
+ | service nginx start | ||
+ | |||
+ | That's it. Point your webbrowser to http://<your webserver fdqn>/app1 | ||
+ | |||
+ | Optimization still to be done. I think I start on [https://www.techatbloomberg.com/blog/configuring-uwsgi-production-deployment/ this place] |
Revision as of 17:07, 21 November 2020
Basics
Check this[1]
Hello world app:
#!/usr/bin/env python3
from flask import Flask
print(__name__)
app = Flask(__name__)
@app.route('/')
def welcome():
return 'Welcome'
if __name__ == '__main__': # When executed on the commandline (build in webserver)
app.run(host='0.0.0.0',port=5000) # Listen to localhost port 5000, you can also use flask run for options
#app.run(host='0.0.0.0',port=8080,Debug=True) # Run in debug mode, listen to all hosts on port 8080
Run the build-in server listening to all
export FLASK_APP=welcome_app.py
flask run --host=0.0.0.0
welcome_app * Serving Flask app "welcome_app" * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
Now you can browse to <serverIP>:5000
Integrate with nginx
Mayor part is from this site [2].
- Install uwgi-emperor and it's python plugin
Configuration files I used.
- Generic configuration file (/etc/uwsgi-emperor/emperor.ini):
[uwsgi] # try to autoload appropriate plugin if "unknown" option has been specified autoload = true # enable master process manager master = true # spawn 2 uWSGI emperor worker processes workers = 2 # automatically kill workers on master's death no-orphans = true # place timestamps into log log-date = true # user identifier of uWSGI processes (same as who runs the web-server) uid = www-data # group identifier of uWSGI processes (same as who runs the web-server) gid = www-data # vassals directory emperor = /etc/uwsgi-emperor/vassals plugins = python3
- Application configuration file (/etc/uwsgi-emperor/vassals/welcome.ini)
[uwsgi] #application's base folder base = /var/www/flask #python module to import app = welcome module = %(app) pythonpath = %(base) #socket file's location socket = /var/local/uwsgi/%n.sock #permissions for the socket file chmod-socket = 664 #the variable that holds a flask application inside the module imported at line #6 callable = app #location of log files logto = /var/log/uwsgi/%n.log plugins = python3
- Create a virtual webserver (port 80 is save enough if you have a secure front-end server)
server {
listen 80 ;
listen [::]:80 ;
root /var/www/flask;
server_name <fqdn>;
location / {
include uwsgi_params;
uwsgi_pass unix:/var/local/uwsgi/welcome.sock;
}
}
Generate web pages
https://flask.palletsprojects.com/en/1.1.x/patterns/templateinheritance/#template-inheritance
Put a index.html in <app-base>/templates/
#!/usr/bin/env python3
from flask import Flask, render_template
print(__name__)
app = Flask(__name__)
@app.route('/html')
def static_page():
return render_template('index.html')
if __name__ == '__main__':
app.run(host='0.0.0.0',port=5000,debug=True)
Microservices and/or more applications on 1 web-server
Starting with this page and additional a lot more we got it working on raspberry pi debian.
- Make python3 the default
cd /usr/bin;rm python;ln -s python3 python
- Install uwsgi and python plugin
apt install uwsgi uwsgi-plugin-python3
- install nginx
apt install nginx-full
I had to make a small change in the nginx configuration;
vi /etc/nginx/conf.d/my.conf
server_names_hash_bucket_size 64;
Super simple apps
In /var/www/flask/app1/app1/py
#!/usr/bin/env python3
from flask import Flask
import os
application = Flask(__name__)
@application.route('/app1')
def app1():
return "App 1 live and kicking"
if __name__ == '__main__':
application.run(host='0.0.0.0', port=8080,debug=True)
/var/www/flask/app2/app2.py
#!/usr/bin/env python3
from flask import Flask
import os
application = Flask(__name__)
@application.route('/app2')
def app2():
return "App 2 live and kicking"
if __name__ == '__main__':
application.run(host='0.0.0.0', port=8080,debug=True)
uwsgi configuration
/etc/uwsgi/apps-available/emperor.xml
<uwsgi>
<autoload>true</autoload>
<no-orphan>true</no-orphan>
<emperor>/etc/uwsgi/vassals-enabled</emperor>
<master>true</master>
<emperor-nofollow>true</emperor-nofollow>
<processes>1</processes>
<uid>www-data</uid>
<gid>www-data</gid>
</uwsgi>
/etc/uwsgi/apps-available/apps.xml
<uwsgi>
<plugins>python3</plugins>
<master>false</master>
<processes>1</processes>
<vaccum>true</vaccum>
<chmod-socket>666</chmod-socket>
<socket>/tmp/%n.sock</socket>
<uid>www-data</uid>
<gid>www-data</gid>
<pythonpath>/var/www/flask/%n</pythonpath>
<module>%n</module>
</uwsgi>
Make them available
cd /etc/uwsgi/apps-enabled
ln -s ../apps-available/emperror.xml
cd /etc/uwsgi/vassals-enabled
ln -s ../apps-available/apps.xml app1.xml
ln -s ../apps-available/apps.xml app2.xml
Create a nginx virtual host
/etc/nginx/sites-enabled/apps.conf
server {
listen 80;
server_name <your webserver fdqn>;
index index.html;
root /var/www/flask;
location /app1 {
include uwsgi_params;
uwsgi_param SCRIPT_NAME /app1;
uwsgi_modifier1 30;
uwsgi_pass unix://tmp/app1.sock;
}
location /app2 {
include uwsgi_params;
uwsgi_param SCRIPT_NAME /app2;
uwsgi_modifier1 30;
uwsgi_pass unix://tmp/app2.sock;
}
}
Start things
service uwsgi start service nginx start
That's it. Point your webbrowser to http://<your webserver fdqn>/app1
Optimization still to be done. I think I start on this place