One of the best ways of understanding your data is to interact with it. This requires being able to easily and rapidly build interactive applications. These applications can range from simple forms to gather user input inside Jupyter notebooks, to full-blown dashboards and web applications that are deployed to the cloud. Meerkat brings interactivity to your fingertips by unifying Python programming and frontend development.
In Meerkat, interactivity is a way to observe and modify the state of your program. More specifically, the way we interact with an interface tells us how the program should run or update state. Modifying the state of some variable(s) can also trigger other states to change.
Underneath the hood, Meerkat relies on a FastAPI Python backend, coupled with Svelte for the frontend.
There are some key distinctions between Meerkat and other tools that allow users to build interactive applications:
Compared to tools like Streamlit, Meerkat is much more focused on supporting data and machine learning use cases. It is likely to be a better fit for users that want to bring the full power of a frontend framework like Svelte to their data science workflows.
Compared to tools like Gradio, Meerkat is much more focused on complex, reactive applications, rather than demos. It is likely to be a better fit for users that want to build full-blown applications that involve ML models, graphing and interactivity.
Compared to Python-to-React compilation approaches like Pynecone, Meerkat is more opinionated about providing a solution for the average data science and machine learning user.
Most data science and machine learning workflows revolve around Python, and Meerkat brings the ability to build reactive data apps in Python to these users.
In this section, we will discuss the workhorses behind interactivity in Meerkat.
When we interact with any interface, changing some state can also impact how the program behaves - i.e. what other states should change and what operations should be re-run. In other words, modifying the state of some variable(s) can trigger events and state changes.
In Meerkat, we can configure this trigger pipeline through reactive functions. When the state of an input into a reactive function changes, the function will re-run. If outputs of these functions are also inputs to other reactive functions, then those functions will also re-run. This allows us to create a reactive chain.
Interactive applications also need to communicate with the backend to tell it what to run or how to update state.
Meerkat supports this with
Endpoints can serve as API endpoints for Meerkat frontends and can be used to modify state in response to user input or events.
An interactive application also needs some way of creating variables that capture the state of the application. This is important to:
keep track of application state that is going to change over time
keep this state in sync between the frontend and Python code
provide explicit ways to manipulate this state
implement and debug the application in terms of this state
In Meerkat, this can be done with
One special markable object is the
Store. Stores can wrap arbitrary Python
objects to make them traceable and responsive to state changes.
Modular applications are easier to build and reuse. But they require well-designed building blocks to be effective.
This can be done with components, which are the main abstraction for building user interfaces in Meerkat. Users can build their own components and repurpose built-in components for designing new interfaces.
All interactive applications need to display data. However, programming custom display logic for each data type can be tedious.
Meerkat provides a simple way to define custom display logic for your data types with
As a user, you can define different formatters for different data types (i.e. columns in your DataFrame) to display data in consistent and easy ways.
Formatter groups can define different modes for displaying data. For example, you many want to display images in different sizes (e.g. thumbnails, icons, original size, etc.).