Building the Blank Canvas
Published: 2023-08-30 18:32:44

tldr: we will review the environment set-up for a project from scratch for a basic application stack built from React, as front-end, and Flask, as back-end.

To begin, we’ll create a directory with the name of our project in the terminal.

`mkdir *project name*` 

Next, we’ll create our virtual environment for python with:

`pipenv python –-3.8` 

We can install any packages we need at this point with:

`pipenv install *package01_name* *package02_name*…` 

Next, we can create our server folder with `mkrdir server` and begin populating our backend files such as `models.py` into that folder. Assuming `flask` has been installed and an `app.py` has been created and configured, we can initialize our database next (from within the `/server` directory:

`flask db init` 

Once we start writing our models, we can also run our first migration with the following:

`flask db migrate -m “commit message”`
`flask db upgrade`

Typically, configuration is factored into its own file, i.e. `config.py` so that `app.py`, `models.py`, and eventually `seed.py` (containing code that seeds the database) will simply import whatever is needed from `config.py`. Note the port number that your backend runs on, usually specified at the bottom of `app.py` in the following two lines of code (we’ll need this later in the frontend):

```
if __name__ == '__main__':
    app.run(port=5555, debug=True)
```

Moving back up to our parent directory, we can proceed with:

`git init`

This command initializes git in your directory. We should have the following three directories in our parent directory: `.venv`, which contains our virtual environment for python, `.git`, containing git configuration files, and `/server`, from which we’ll build our backend.

Now we can initialize our frontend with:

`npx create-react-app client`

This creates a new folder in our parent directory named `client` and populates it with a basic starter template for our React frontend. Note that although the order in which we carry out these steps is not crucial, creating our React app must be done after `git init`; Otherwise, the above command will run its own `git init` which will create a submodule within your directory structure, making organizing git commits tedious and meticulous. Ergo, always run the above command after `git init` in the parent directory. That being said, next we can cd into this directory and begin installing our frontend dependencies with:

`npm install *packageName01* *packageName02*…`

Lastly, we’ll add the backend port number into our `package.json` in the following line:

` "proxy": http://localhost:xxxx` where `xxxx` is your backend port number. 

Now we can start our app with two terminal windows. In the first, navigate to `/server` within the pipenv shell and run: `python app.py`. In the second, navigate to `/client` and run: `npm start`. In a few moments, your template application will be opened in your browser! 

An example `config.py` is provided below:

```
from flask import Flask
from sqlalchemy import MetaData
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_restful import Api
from flask_bcrypt import Bcrypt
from flask_cors import CORS
import os

app = Flask( __name__ )
BASE_DIR = os.path.abspath(os.path.dirname(__file__))
DATABASE = os.environ.get(
    "DB_URI", f"sqlite:///{os.path.join(BASE_DIR, 'app.db')}")
app.config['SQLALCHEMY_DATABASE_URI'] = DATABASE
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

md = MetaData(naming_convention={
    "fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
    "uq": "uq_%(table_name)s_%(column_0_name)s",
    "ck": "ck_%(table_name)s_%(constraint_name)s",
    "fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
})

db = SQLAlchemy( metadata = md )
CORS( app )
Migrate( app, db )
db.init_app( app )
api = Api( app )
bcrypt = Bcrypt( app )

app.secret_key = ‘secret-key-here’
```

Don’t forget to replace `secret-key-here` with your own secret key generated with the command ` python -c 'import os; print(os.urandom(16))'` run from your shell.