Hi. I'm Mark Wallace. In my role as a an Ontologist and Software Architect, I am continually working with new and fun semantic technologies. Be it RDF/OWL, Triple-stores, Semantic Wikis, or Text Extraction, I am learning more all the time and want to share my experiences in hopes of helping others along with these technologies. I hope post a new article every month or two, so check back in every so often to see what’s cooking!

Friday, February 22, 2019

Simplest Python/Flask + React-JS App

Motivation

I wanted to create the simplest Python/React server/client app I could.

There are many quick ways to create a React app, including create-react-app documented here. This is probably best for production, but it does create a lot of bloat. E.g., a sample hello world app created a folder tree containing 29,701 Files and 4,541 Folders! Additionally, it is all JavaScript, i.e., no python. It uses Node.js on the back-end. My projects tend to use Python/Flask for the backend (BE), and HTML/JS for the front end (FE).

I also found some help to create Python/Flask BE and JS/React FE, documented here. Its hello world only created a folder tree containing 2,936 Files, 239 Folders. But it did not seem to show interaction from the React GUI back to a REST API on the server. It seemed to use templates instead, which are really a type of server-side scripting. I was looking for an example of a REST API on the BE in Python/Flask, and how to call back to that REST API from a React FE client.

So, I rolled my own.

Now to keep this THE SIMPLEST, I did not use frameworks that minify and otherwise manage efficiently bundling and sending GUI code from the server. Again, this is great for production, but I wanted to just understand the concepts, and keep things as SIMPLE as possible. So the version I'll show you has the JSX compiling happening in the browser. This can be improved when I need to make things more complex and production ready.


So here is my version. It takes 3 files and 1 sub-folder. :) 






What the App Does


In this sample FE/BE app, the FE client calls the

     GET /ip 

HTTP method on the BE server to get the server's IP address. The BE calls out to another service, https://httpbin.org/ip, to get the server's external IP address. It returns this as JSON to the client. Since the httpbin.org service takes a little while (on my computer), you get a chance to see the React-based GUI render initially, then render again when the data data becomes available (the `tbd` is replaced by the real IP address).

The Server

This is the entire code of the server, which is in file app.py. It uses Python Flask to define 2 API endpoints, the root endpoint ('/'), and the "IP address" endpoint ('/ip').

from flask import Flask, render_template, jsonify
import requests

app = Flask(__name__)  

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/ip')
def ip():
    response = requests.get("https://httpbin.org/ip")
    json = response.json()
    result = json['origin'].split(',')[0]
    return jsonify({"ip":result})

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

The Client

This is the entire code of the client, which is in file templates/index.html. It uses React JS to define 2 components, an outer one and an inner one. The outer one called  <Display />  has some basic HTML structure for the overall app. The inner one called  <ShowIp />  renders the IP address returned from the server.

<html>

<head>
  <script src="https://unpkg.com/react@15/dist/react.min.js"> </script>
  <script src="https://unpkg.com/react-dom@15/dist/react-dom.min.js"> </script>
  <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
</head>

<body>
  <div id="root"></div>
  <script type="text/babel">
    /* ADD REACT CODE HERE */

    /* ref:
     * https://medium.freecodecamp.org/learn-react-js-in-5-minutes-526472d292f4
     */

    class ShowIp extends React.Component {
      constructor() {
        super();
        this.state = {
          ipValue: "tbd"
        };
        console.log('ctor')
      }
      
      componentWillMount() {
        console.log('willmount')
               
        fetch('/ip')
        .then(results => {
            return results.json();
          })
        .then(data => {
            console.log(JSON.stringify(data))
            this.setState({ipValue: data.ip});
          })
        }

      render() {
        return (
          <h3>Server's IP addr is: {this.state.ipValue} </h3>
        );
      }
    }

    class Display extends React.Component {
      render() {
        return (
          <div className="main">
          <h1>Welcome to the app</h1>
            <div className="ip">
              <ShowIp />
            </div>
          </div>
      );
      }
    }

    ReactDOM.render(
      <Display />, 
      document.getElementById("root")
    ); 

  </script>
</body>

</html>


To Run

To run it, do the following a Windows command prompt:

 set FLASK_APP=app.py
 set FLASK_ENV=development
 flask run


Then open your browser to:


You should see a (boring) UI that shows the IP address of the server you are running on.



That's about it.  If you give it a try, let me know how it goes, so I can improve this post.
The code is here on github.

Thanks,
 -Mark

1 comment:

Followers