The aim of this article is to help you start your own full-stack web application with a Python Flask server and a React front-end.
Installation of basic requirements
Installing Python and Setting Virtual Environment
- Install python 2.7 or 3.xx
- Add environment variable for bin/python.exe
- Easy install pip
- Install virtualnev
- Command in custom directory [virtualnev venv] so it will create virtual environment in particular directory.
Installing MySQL
- Download MySQL from official website.
- Or download xampp server which also have php myadmin so you can visually see the database
- Or download MySQL workbench
- Add path variable for MySQL
Minimal Requirements for Flask app with MySQL
- pip install Flask
- pip install flask-MySQL
- pip freeze is useful for print the all dependency of that python app. So after these all steps now MySQL, venv is running. And flask also settled up.
Chapter 1. Developing Minimal Flask App
1. App.py:
#Flask has the object of app to execute.
# to render a template you can use the render_template () method.
#all configuration we should save in different file so we will create a config.py and will pass the class of config.py into from_object method of flask.
from flask import Flask,render_template :
app = Flask(__name__)
app.config.from_object('config.DevelopmentConfig')
@app.route("/")
def main():
return “Welcome to Flask World”
if __name__ == "__main__":
app.run()
2. Config.py
Flask provides default config or env values so we have two ways to pass these values.
The one way is:
App.config[‘DEBUG’] = True;
But the Best way is to Create a BaseConfig class and write the common config there and after that we can override these properties by extending this BaseConfig class into another class.
DEBUG = true means flask app will automatically reload after any change in code.
class BaseConfig(object):
DEBUG = True
TESTING = False
class ProductionConfig(BaseConfig):
DEBUG = False
class DevelopmentConfig(BaseConfig):
DEBUG = True
TESTING = True
Chapter 2. Setting the Structure for extending our Flask application
|---backend
|---venv (virtual environment)
|---webapp
|---routes
|---routes.py
|---__init__.py (to make this folder work as package)
|--__init__.py
|---config.py
|---db.py
|---run.py
|---req.txt
|---frontend
|---static (all static files)
|---css
|---external js
|---bundle.js
|---images
|---js (frontend folder) [Setting React Structure]
|---components
|---route.js
|---index.jsx
|---node_modules
|---.babelrc
|---package.json
|---webpack.config.js
|---index.html
this structure is most recommended because frontend and backend development independently is always good choice.
backend will be serving from : python run.py and fronted will be serving from : /frontend/static npm run watch && /frontend/ http-server
Chapter 3. explaining the structure with code
1. run.py
We are getting configuration from our config.py
and setting through from_object method of flask.
And we have defined our app in webapp folder’s __init__.py
so we importing app .
2. Db.py
We want our db connection in separate file.so this file returns cursor object of mysql queries.
from flaskext.mysql import MySQL
from webapp import app
def getDb():
mysql = MySQL()
mysql.init_app(app)
conn = mysql.connect()
cur = conn.cursor()
return cur
3. config.py
This is our config file which have all common config which are global. This is known as class based setting.
class BaseConfig(object):
DEBUG = True
TESTING = False
MYSQL_DATABASE_USER = 'root'
MYSQL_DATABASE_PASSWORD = ''
MYSQL_DATABASE_DB = 'zenmeds_dump'
MYSQL_DATABASE_HOST = 'localhost'
class ProductionConfig(BaseConfig):
DEBUG = False
class DevelopmentConfig(BaseConfig):
DEBUG = True
TESTING = True
4. Webapp/init.py
As we mentioned earlier that we created our app component in webapp folder.
Here we have given our static folder and template folder values .and importing routes in this.
We are using blueprint here so we will use this instead of @app.route()
Here we don’t need static_folder directory because we have separated our frontend and backend .
So we will only send json from here. And we will show in frontend us js controllers.
from flask import Flask
import config
app =Flask(__name__,static_folder ="./static",template_folder="./templates")
app.config.from_object('config.DevelopmentConfig')
from webapp.routes.routes import route_blueprint
#register the blueprint app.register_blueprint(route_blueprint)
5. routes.py
Here is we have defined our basic route and importing db.py which will initialise here only . And it is rendering index.html Here we don’t need render_template function. According to our 2nd structure.
from webapp import app
from flask import render_template,Blueprint
import db
route_blueprint = Blueprint('route',__name__)
cur = db.getDb()
@route_blueprint.route("/")
def main():
cur.execute("Select medicine_name , medicine_composition from medicine_detail")
result = cur
return render_template('index.html',result=result)
6. routes/init.py
Empty
so our backend part is completed so now we can set up react in our frontend folder.
##Installing dependencies for our react frontend
- first we have to install npm.exe in our system.
- Create package.json in frontend directory using command
npm init
- Install from package.json which includes babel, react, webpack, loader
7. package.json
{
"name": "webapp",
"version": "1.0.0",
"description": "Creating a full stack wep app with Flask, NPM, Webpack, and Reactjs",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack -p --progress --config webpack.config.js",
"dev-build": "webpack --progress -d --config webpack.config.js",
"watch": "webpack --progress -d --config webpack.config.js --watch"
},
"repository": {
"type": "git",
"url": "git+https://github.com/xyz/my-portfolio.git"
},
"keywords": [
"portfolio",
"template",
"python",
"react",
"npm",
"webpack"
],
"author": "",
"license": "ISC",
"bugs": {
"url": "https://github.com/xyz/my-portfolio/issues"
},
"homepage": "https://github.com/xyz/my-portfolio#readme",
"devDependencies": {
"@babel/preset-react": "^7.0.0",
"babel-core": "^6.26.3",
"babel-loader": "^7.1.5",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"react": "^16.8.3",
"react-dom": "^16.8.3",
"webpack": "^4.29.5"
},
"dependencies": {
"history": "^4.7.2",
"react-router-dom": "^4.3.1"
}
}
8. webpack.config.js
const webpack = require('webpack');
const resolve = require('path').resolve;
const config = {
devtool: 'eval-source-map',
entry:__dirname + '/js/index.jsx',
output:{
path:resolve('./static'),
filename:'bundle.js',
publicPath: resolve('./static')
},
resolve: {
extensions:['.js','.jsx','.css']
},
module: {
rules: [
{
test: /\.jsx?/,
loader: 'babel-loader',
exclude: /node_modules/,
query:{
presets: ['react','es2015']
}
},
{
test: /\.css$/,
loader: 'style-loader!css-loader?modules'
}]
}
}
};
module.exports = config
9. .babelrc
{ presets: ['react', 'es2015'] }
so now we have installed all the frontend dependencies . webpack is working as bundler . css loader is also there .
now we just have to mention our index.html which will have div with id from that id index.js will point .
and after we can add our react components and controllers .
here I am mentioning four files . index.html, index.js, route.js and home.jsx.
###10. index.html
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="static/css/main.css">
<title>creating a Full-Stack Python Application with Flask, NPM, React.js and Webpack</title>
</head>
<body>
<div id="content" />
<script src="static/bundle.js" type="text/javascript"></script>
</body>
</html>
11. Index.js
import React from 'react';
import ReactDOM from 'react-dom';
import routes from "./route";
ReactDOM.render(routes, document.getElementById("content"));
12. home.jsx
import React, { Component } from 'react';
export default class Home extends Component {
render() {
return (
<h1>Hello</h1>
)
}
}
13. route.js
import React from 'react';
import { HashRouter, Route, hashHistory } from 'react-router-dom';
import Home from './components/Home';
// import more components
export default (
<HashRouter history={hashHistory}>
<div>
<Route path='/' component={Home} />
</div>
</HashRouter>
);
Now frontend is served by (localhost: 8080) /frontend/static npm run watch && /frontend/ http-server Backend is served by (localhost: 5000) python run.py Mysql is running on localhost: 3306>In next version of document I will explain how to connect frontend with backend using http request. How to send request? How to get response?
References (ctrl+click to follow link):
a. https://www.bogotobogo.com/python/Flask/Python_Flask_Blog_App_Tutorial_1.php b. https://github.com/jwkvam/minimal-flask-react/tree/master/templates c. https://github.com/Einsteinish/FlaskBlogApp d. https://code.tutsplus.com/tutorials/creating-a-web-app-from-scratch-using-python-flask-and-mysql--cms-22972 e. medium blog of eyong kevin f. https://itnext.io/a-template-for-creating-a-full-stack-web-application-with-flask-npm-webpack-and-reactjs-be2294b111bd