•March 27th 2020
This article is the first installment of a tutorial series focused on how to create a full-stack application using Flask, React/Redux and Stream. This tutorial is an adaptation of my previous series on creating a Stream-based web app with Flask, so be sure to check it out to understand some of the structure behind it if you haven't already. In this piece, we set up the basic structure of our application with Server Side Rendering (SSR). Be sure to check out the repo to follow along!
This article assumes that you have npm installed and ready in your development environment, as well as a new directory initialized with a virtual environment.
We use SSR for our React application for a few key reasons. First, rather than splitting our code into two separate repositories simultaneously for server and client, we can combine it into one. Second, it allows us to avoid bothersome CORS-related issues while we develop by having all requests come from the same domain. Third, it gives us leeway to use some familiar packages (like flask-login) for authentication purposes, sparing us having to rewrite our functions and endpoints to use JWT instead.
Our first step is to set up the basic skeleton of our project. Once we have the bones in place, we can start fleshing out specific aspects on which we are working. Similarly to our last project, we start with an empty directory initialized with a new virtual environment. Next, we install Flask itself along with a few base packages with
pip install flask flask-sqlalchemy flask-login flask-wtf stream-python flask-migrate
From The Top
First up in the structure is to create our top-level Python files and directories. As this project is very similar on the backend to the previous series, we port most of the backend code directly over to save time and to avoid repeating familiar concepts. Be aware that there are differences between the two codebases as we go along.
We start by defining our application.py file (in
After that, we set up our configuration file. This step includes best practices in dividing up our Stream keys as well as preparing to use AWS SES for emails copied from the end of the last tutorial (in
In continuation, we create our app directory that houses the majority of our application logic, along with an initialization file (in 'app/init.py')
You notice that our Flask initialization has new arguments for static and template folders. We have not used these arguments yet, but this helps Flask to understand from where we are serving our React App, and where to search for the static files that we create.
And By Extension
Next up is our extensions (in
Considering that we have initialized Flask login, the application is expecting a user_loader function, even though we aren't directly asking for credentials. As we already defined all of our model objects from our previous project, we can directly transfer over that file (in
We must initialize the database and create the tables to allow for Flask-login as well, so we can do that now as well with
flask db init,
flask db migrate, and
flask db upgrade in the CLI.
Just For Decoration
To speed up our development, we transfer over our route decorators that determine permission levels for users (in
Along the same lines of logic outlined above, we include the email function that we developed earlier as well (in
Next, we create our main directory where we host our (you guessed it!) main application routes. Once again, we must create an initialization file for it (in
Now that our main directory is built with an initialization file, we can move onto our views. To start, we only have one view to return the index.html file that we create, so we need to set that up (in
The Flask backend of our application is finished for now!
Now that the backend is created, we can move on to building the React application that returns. This part is a bit more hands-on than a simple 'create-react-app', but it is still very straight-forward.
In our app directory, create a new directory named 'static', followed by subdirectories' css', 'dist', 'images' and 'js'. These elements help to keep our project organized between different components (in a broad sense) as we continue to develop. Now, using the command line, navigate to the static folder using
Finally, initialize the project with
npm init. We are guided through our configuration for the newly created package.json, which I have used the following values for:
After you have created your package.json file, our next step is to install webpack from the command line, en
npm i webpack --save-dev
Once we install this element, create a webpack configuration file in your static directory (in 'app/static/webpack.config.js')
Now, we need to install babel to convert the jsx files. In the command line, install babel with
npm i @babel/preset-env @babel/preset-react --save-dev.
We also need to create a babel presets file to handle conversions (in
After, we have to add a babel-loader rule to the webpack config, which excludes any files node modules to speed up our loading times (in
Our last steps include creating our index files, which are the base of our React web application. These files consist of the index.html file, which is rendered by our "view" function to a user requesting our site. The second component is a index.jsx file, which contains the React logic rendered to the page.
First, we create the index.html file (in 'app/static/index.html')
Followed by the index.jsx file (in ‘app/static/js/index.jsx’)
Building The Builders
Our final step is to create our build files within the package.json file to update our dependencies.
(I have included a proxy to avoid CORS-related issues that might spring up along the way from opening files in an unorthodox manner.)
Before moving on, we need to generate our first build of the React application by running
npm run watch. While there shouldn't be any dependency issues if you have followed the instructions up until to this point, if any problems arise during the build, run
npm install and try again.
Now, your application tree should look like this:
To check that everything is working correctly, open a new CLI or exit the build with CTRL+C and navigate back to the top level of Flask project. From there, set the application with
set FLASK_APP=application.py in the command line and enter
flask run. When we open up our browser to localhost (http://127.0.0.1:5000), our app should render!
As a helpful tip, be sure to clear your browser cache between new builds, as most web browsers store previous versions of your application, which can cause headaches while you develop.
At this point, we have the structure in place to start to develop your Full Stack Application. Now that we have set up these essential elements, we can begin to develop our authentication functions to verify users and create profiles. Look for these steps in the next tutorial!
As always, thanks for reading, and happy coding!
Note: The next post in this series can be found here