Viet Phan X

Building MVP with Flask Day 1 – Dev setup

πŸ‘¨β€πŸ’» Software Development
5019
Feb 19, 2019

In this post, I will describe the process of starting a Flask project from scratch.

This post is a part of the article series about building an MVP with Flask

First things first.

I am not a software developer, so you might have a hard time following my thoughts or tutorial steps. My intention is not to make yet another cookie-cutter tutorial. There are plenty of them on Medium.

The main goal of this series is to document the whole process of making an MVP with emphasis on mistakes, that I make along the way.

Hardware & Software Requirements

For the record. The project is done on Macbook Pro 2018 with macOS Mojave 10.14.3.

That being said. All software tools, libraries or packages are tailored for Mac OS Unix environment. You might want to install Windows equivalents if you are a Windows user.

I used the following software in various stage of development:

  • Homebrew
  • iTerm2
  • Nginx
  • Gunicorn
  • Python
  • Visual Studio Code
  • PyCharm

I won't cover them in this tutorial, so make sure you have them installed.

Create Project Folder

Let's start a project by creating a dedicated project folder.

I will call it Financia because it is the name of my domain. You can call it MyProject if you will.

mkdir financia

Now go to the newly created project folder.

cd financia

Setup Virtual Environment

Set a virtual python environment in the newly created project folder.

pipenv shell

This will create a special development environment just for our project. A sandbox, where we can install whatever python library we want without influencing system level installed python libraries.

Install Flask

Finally install Flask, a micro web framework for Python.

pipenv install flask

Installation failed due to some strange error.

Adding flask to Pipfile's [packages]...
Pipfile.lock not found, creating...
Locking [dev-packages] dependencies...
Locking [packages] dependencies...
lib/python3.7/site-packages/pipenv/utils.py", line 402, in resolve_deps
    req_dir=req_dir
  File "/usr/local/Cellar/pipenv/2018.7.1/libexec/lib/python3.7/site-packages/pipenv/utils.py", line 250, in actually_resolve_deps
    req = Requirement.from_line(dep)
  File "/usr/local/Cellar/pipenv/2018.7.1/libexec/lib/python3.7/site-packages/pipenv/vendor/requirementslib/models/requirements.py", line 704, in from_line
    line, extras = _strip_extras(line)
TypeError: 'module' object is not callable

It looks like pip cannot install Flask.

After furious googling I found out, that is is caused by a bug in the newest pip version.

The solution is to revert to the older pip version.

pipenv run pip install pip==18.0

The older version of pip was reinstalled.

Collecting pip==18.0
  Using cached https://files.pythonhosted.org/packages/5f/25/e52d3f31441505a5f3af41213346e5b6c221c9e086a166f3703d2ddaf940/pip-18.0-py2.py3-none-any.whl
Installing collected packages: pip
  Found existing installation: pip 19.0.1
    Uninstalling pip-19.0.1:
      Successfully uninstalled pip-19.0.1
Successfully installed pip-18.0

Let's try to install Flask again.

pipenv install flask

Good. Flask was successfully installed.

2019 02 07 17 23 38 Flask Installed

Setup Python DEV IDE

It's time to decide which dev IDE or code editor to use. I can use either Visual Studio Code, which is a great text editor for any language, or PyCharm, a Python only dev IDE, that offers tight integration with Flask.

Integration with Flask is not turn-key though. Found a guide, that explain how to setup Flask with PyCharm. After 5 minutes of reading, I decided to skip this option.

I don't want to waste time in the beginning. Yes, I won't be able to use PyCharm debugger, but I can always set it up later.

Create Flask Boilerplate App

Anyway, let's create a new python file named app.py and insert this boilerplate code to create our first Flask app.

from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello():
    return "Hello World!"

if __name__ == '__main__':
    app.run()

Thats it. We imported Flask library. Created an app called app with a method, that prints "Hello World!".

The method is wrapped with a route decorator, that tells the browser to execute the "hello" method if the user visits the homepage.

Setup custom localhost domain

It would be nice to assign custom localhost domain to our Flask app like "app.local" instead of "localhost" or "http://127.0.0.1".

But how?

I remember, that similarly to PHP and Wordpress, python web frameworks need an HTTP server and a proxy to serve python scripts to the browser.

In this case, the most frequent choice is to use Nginx and Gunicorn. Nginx is installed, but what about Gunicorn? Does it need to be installed individually in our virtual environment?

It appears so according to this guide.

Okay, install Gunicorn then.

pipenv install gunicorn

Now back to custom URLs. I need to add hosts to the Nginx configuration.

Go to folder /private/etc/hosts, where the hosts config file is located.

Open the file and add a custom domain.

##
# Host Database
#
# localhost is used to configure the loopback interface
# when the system is booting.  Do not change this entry.
##
127.0.0.1 financia.local

Type our custom domain into Chrome and try if it loads the app.

No, luck. Google is loaded instead.

Maybe restarting Nginx will help?

sudo brew services restart nginx

Or restart Gunicorn...

gunicorn financia.wsgi

Oops, this command doesn't work.

ModuleNotFoundError: No module named ‘financia'

Okay, what about running Flask directly from the command console? If it works, then we can continue.

python app.py

Yep, Flask works.

2019 02 07 17 58 17 Run Flask App From Console

And browser shows...

2019 02 07 17 58 43 Flask Running in Browser

We can stop Flask now.

ctrl+c

So Gunicorn works and the only thing left is Nginx configuration.

Go to folder /usr/local/etc/nginx/nginx.conf, open config file and add new configuration for our app.

server {
listen 80;
server_name financia.local;

access_log /financia/nginx/logs/access.log; # <- make sure to create the logs directory
error_log /financia/nginx/logs/error.log; # <- you will need this file for debugging

location / {
# checks for static file, if not found proxy to app
try_files $uri @proxy_to_app;
}

location @proxy_to_app {
proxy_pass http://financia.local:5000; # <- let nginx pass traffic to the gunicorn server
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /static {
root /fiancia/static/; # <- let nginx serves the static contents
}
}

Accordingly create new folder for Nginx logs /financia/nginx/logs/

And a root folder for static files /fiancia/static/

Restart nginx again.

sudo brew services restart nginx

Still not working. Maybe Gunicorn is missing some configuration?

Create new file gunicorn.conf.py in our project folder.

Add following config to the file.

bind = "financia.local:5000" # Don't use port 80 becaue nginx occupied it already.
errorlog = '/financia/gunicorn/logs/gunicorn-error.log' # Make sure you have the log folder create
accesslog = '/financia/gunicorn/logs/gunicorn-access.log'
loglevel = 'debug'
workers = 1 # the number of recommended workers is '2 * number of CPUs + 1'

Accordingly create new folder for Gunicorn logs /financia/gunicorn/logs/

Now try to enter url http://financia.local:5000 into Chrome.

2019 02 07 18 11 35 Financia.local 5000 768x601

Hmm, maybe http://financia.local will work instead of http://financia.local:5000.

2019 02 07 18 19 59 Gunicorn 502 Bad Gateway

Bad gateway error :(.

Time to look into Gunicorn documentation. Apparently, Gunicorn is not running at all.

Okay, found out, that the correct way to start Gunicorn with Flask is to execute command financia:app instead of financia:wsgi. WSGI is a Django framework thing, not Flasks.

Let's try a new command.

financia:app

The same error appears.

no module ModuleNotFoundError: No module named ‘financia'

Now I notice, that our Flask app doesn't contain any string with value "financia".

Could it be possible, that I should use the name of the flask App?

gunicorn app:app

Hurray! Now it works.

2019 02 07 18 33 18 Financia.local Works 1

That would be all for today.

In the next session, I would like to add the Bootstrap 4 CSS framework, create a homepage using Flask templating system and design header for our app.


You need to Build a

Micro Startup

I can bring your ideas to life - free of charge.

Book a free consultation and let’s identify opportunities to turn your vision into a successful business.

15 min call

Get idea feedback


If You Like what I do
You can buy me a coffee πŸ‘‡
Send β˜• via PayPalSend β˜• with Bitcoin

πŸ€™ Let's connect

Made by Viet Phan Β© 2018-2024Privacy Policy