Intro
I work at a cool company named Imubit. This company creates AI solutions for refineries.
At the beginning of the year, we decided to create a team that will create internal data science and data investigation tools. After a lot of discussion, we landed on building those tools in JupyterLab.
My task was (and still is) to create data visualization tools that let the user query big amount of data, modify it and visualize it in charts and heat maps.
The problem
The applications became bigger and bigger, and had components that were used in multiple different applications. This created a situation where I needed to find a way to manage and share data between multiple components, across multiple applications.
The light bulb
As a frontend developer I knew what I needed right away: State management.
The idea was simple: I need a single source of truth to all components, that will hold the current user selections and cache the current queries results. This source should be able to notify a component on a data change.
Now, if I was using React for example, I would probably go for MobX, but sadly, it does not exist for Python.
Solution
My solution was a Proxy inspired idea: Create a class that inherit dict, and add the option to notify and trigger listeners.
Because we are dealing with Python, I did not want to use an Event based mechanism, and preferred to keep is as synchronous is I can.
This will be easier to debug and use in Python.
We start with a “proxy” like solution:
From there we need to add the state management. I chose to use
andset_state(*path, value) - will iterate the path and add the value to that path in self[’state’], will create that path if not exists
get_state(*path) - will iterate the path and return the value if exists.
Now, that we have a state caching, we can add the components update mechanism;
Next step: convert it from a dictionary to a class members and take advantage of the dot-notation.