Building MVP with React Flask Full Stack – Day 1 – Dev setup

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

This post is a part of article series about building a MVP with React Flask Full Stack.

First things first.

I am not a software developer, so you might have 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 a 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 following softwares 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.

 

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

 

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.

 

Flask Installation

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 newest pip version.

The solution is to revert into older pip version.

pipenv run pip install pip==18.0

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.

 

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 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.

 

Flask Boilerplate

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!”.

Method is wrapped with a route decorator, that tells browser to execute “hello” method if user visits homepage.

 

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 needs a HTTP server and a proxy to serve python scripts to the browser.

In this case, most frequent choice is to use Nginx and Gunicorn.

Nginx is installed, but what about Gunicorn?

Does it need to be installed individually into our virtual environment?

It appear so according to this guide.

Okay, install Gunicorn then.

pipenv install gunicorn

Now back to custom urls. I need to add hosts into Nginx configuration.

Go to folder /private/etc/hosts, where hosts config file is located. Open the file and add 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

Opps, this command doesn’t work.

ModuleNotFoundError: No module named ‘financia'

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

python app.py

Yep, Flask works.

And browser shows…

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.

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

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 new command.

financia:app

Same error appears.

no module ModuleNotFoundError: No module named ‘financia'

Now i notice, that the 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.

That would be all for today.

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

Share it!


Want to support me in my journey 🚀? You can send me a donation below 👇.

Donate with Paypal

Leave a Reply

avatar

Want to support me in my journey 🚀? You can send me a donation below 👇.

Donate with Paypal

Made with 🔥 by Viet Phan 2018