Create a GUI for Python using React

Django Doctor analyses codebases and suggests improvements. It used to be SaaS only, but today we released it as an offline command line tool. This blog post explains how we used React to make a nice UI for our Python command line interface:

For our command line tool we wanted a nice UI. We use React for our website so we considered how to pass data from Python to React and back again, in a way that can easily be distributed via `pip install django-doctor`. We didn’t use Django or Flask as we wanted an apple, not a gorilla holding an apple.

# The code

The following React Component is a form wizard that accepts a list of items and allows the user to choose a subset, then that subset of items is posted to the server:

So `index.js` expects the HTML page it’s being served from to contain an element with ID `context-messages` to contain some JSON serialized data. Now is where the Python comes in. We serve the HTML file using features provided by Python’s build in `wsgiref` library:

Then we can create some command line tool that calls `wsgi.create`:

So now we have bi-directional communication with react and python:

1. A python command line script that runs `check_codebase` then passes `messages` to the wsgi app
2. A wsgi app that renders a HTML file containing `messages`, and (not shown) a `<script>` tag that serves the build react js
3. A React app that hydrates the json and then passes it to form wizard, then ultimately posts the selected items back to `/done/`.
4. a wsgi handler that sees data posted to /done/ and does soemthing with it

Pretty cool. To make it cooler we can replace the http post request and rendering of html with a websocket. Less hacky. Maybe we will eventually use that at [Django Doctor](https://django.doctor/).

# distributing via pip install

`setup.py` is great at distributing Python files, but for this to work we need to make setup.py create a distribution containing Python files and .js and .png and .html etc.

We do that by copying the build react app to `./wizard`, add `__init__.py` to it, then write the `setup.py` like so:

The meat is in `packages` — making sure `wizard` package is included, and `include_package_data` to make sure the non python files are distributed too.

### Try it yourself

Use our command line interface tool to check your Django code for improvements. Run `pip install django-doctor` then `django_doctor fix`.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store