- Create new directory project
mkdir /var/www/flask-app
- Change location to your new created directory project
cd /var/www/flask-app
- Create new Virtualenv for specific python version
virtualenv venv --python=python3.9
- Activate your virtual environment (venv)
source venv/bin/activate
- Install Flask using
pip
pip install flask
- Create new file
app.py
in root project directoryfrom flask import Flask, request, abort, jsonify app = Flask(__name__) @app.route('/getSquare', methods=['POST']) def get_square(): if not request.json or 'number' not in request.json: abort(400) num = request.json['number'] return jsonify({'answer': num ** 2}) if __name__ == '__main__': app.run(host='127.0.0.1', port=8080, debug=True)
- Finally, your project directory should be like this
├── app.py ├── venv │ ├── bin │ ├── lib │ ├── share
- Make sure you've been activating your virtual environment
source venv/bin/activate
- Run flask app
python app.py
- Create new request
After running that command, you should get this message
curl -i -H "Content-Type: application/json" -X POST -d '{"number":5}' http://127.0.0.1:8080/get-square
HTTP/1.0 200 OK Content-Type: application/json Content-Length: 19 Server: Werkzeug/0.16.0 Python/3.9.0 Date: Mon, 23 Nov 2020 15:18:14 GMT { "answer": 25 }
- Make sure you've been activating your virtual environment
- Install Gunicorn package
pip install gunicorn
- Create new file on your root project directory named
wsgi.py
from app import app if __name__ == '__main__': app.run()
- Finally, your project directory should look like this
├── app.py ├── venv │ ├── bin │ ├── lib │ ├── share ├── wsgi.py
- Make sure you've been activating virtual environment
source venv/bin/activate
- Run flask app using Gunicorn web service
You should get this message after running that command
gunicorn --bind 127.0.0.1:8080 wsgi:app
[2020-11-23 06:49:16 +0000] [4166] [INFO] Starting gunicorn 20.0.4 [2020-11-23 06:49:16 +0000] [4166] [INFO] Listening at: http://127.0.0.1:8080 (4166) [2020-11-23 06:49:16 +0000] [4166] [INFO] Using worker: sync [2020-11-23 06:49:16 +0000] [4181] [INFO] Booting worker with pid: 4181
Alternative, you can use IP address "0.0.0.0:8080", instead of "127.0.0.1:8080". Especially in production server.
- Make sure you've been activating virtual environment
- Create new file named
gunicorn.py
inside root project directoryimport multiprocessing workers = multiprocessing.cpu_count() * 2 + 1 bind = 'unix:flask-app.sock' umask = 0o007 reload = True #logging accesslog = '-' errorlog = '-'
- Create systemd file to automatically start Gunicorn service
sudo nano /etc/systemd/system/flask-app.service
- Below is the content of
flask-app.service
file[Unit] Description=Gunicorn instance to serve flask application After=network.target [Service] User=root Group=www-data WorkingDirectory=/var/www/flask-app/ ExecStart=/var/www/flask-app/venv/bin/gunicorn --config gunicorn.py wsgi:app Environment="PATH=/home/root/flask_rest/flaskvenv/bin" Environment="FOO=Bar" [Install] WantedBy=multi-user.target
You could add some configuration (DB connection, App version, etc) by using Environment="FOO=Bar". Just add some couple config there.
- Let's start and enable the service
sudo systemctl start flask-app.service sudo systemctl enable flask-app.service
- Finally, you can check your service whether its running or not
flask-app.service - Gunicorn instance to serve flask application Loaded: loaded (/etc/systemd/system/flask-app.service; enabled; vendor preset: enabled) Active: active (running) since Mon 2020-11-23 04:55:01 UTC; 1h 4min ago Main PID: 19207 (gunicorn) Tasks: 11 (limit: 4647) CGroup: /system.slice/flask-app.service ...
-
Create Apache virtual host config file
sudo nano /etc/apache2/sites-available/flask-app.conf
-
Below is the content of
flask-app.conf
<VirtualHost *:80> ServerAdmin [email protected] ServerName flask-app.example.com ErrorLog ${APACHE_LOG_DIR}/flask-app-error.log CustomLog ${APACHE_LOG_DIR}/flask-app-access.log combined <Location /> ProxyPass unix:/var/www/flask-app/flask-app.sock|http://127.0.0.1:8080/ ProxyPassReverse unix:/var/www/flask-app/flask-app.sock|http://127.0.0.1:8080/ </Location> </VirtualHost>
-
Enable new Apache config
sudo a2ensite flask-app.conf
-
Reload Apache service
sudo service apache2 reload
Congratulation, you have been created new project using Flask and Gunicorn. Now, it's time to test our API.
- Create new request using cURL
curl -i -H "Content-Type: application/json" -X POST -d '{"number":5}' http://flask-app.example.com
- You should get this message
HTTP/1.0 200 OK Content-Type: application/json Content-Length: 19 Server: Werkzeug/0.16.0 Python/3.9.0 Date: Mon, 23 Nov 2020 15:18:14 GMT { "answer": 25 }
- Save your pip package into text file and install them when deploy to your server
- Save
pip
packages into text filepip freeze > requirements.txt
- Install
pip
packages from text filepip install -r requirements.txt
- Save