Our mission at frame.ai is to make it easy to build better relationships with your customers (internal and external) using Slack. As a small team of startup vets, we often need to work quickly and independently, so as Head of Data, I’ve typically built and configured the services I need myself.
Our ability to make quick changes was recently put to the test. Responding to an increasingly common customer need, I was able to design, prototype, and safely deploy a new analytics dashboard to a large subset of Frame’s customers in eight hours. This new dashboard wasn’t just a nice-to-have, either. As a result of it, one of our partners was able to make critical budget decisions that week based on the new visibility this dashboard provided. Our agility made the difference for them.
Now, I’ll readily admit that although I have strong data science background, I’m a middling engineer, at best. So how’d I manage to pull off a non-trivial feature release with new data models, new visuals, and customer-specific functionality that didn’t risk any of our SLAs?
The answer is Looker, along with a custom deployment framework that leverages its code-based approach to analytics. Looker’s architecture made it possible to programmatically automate big parts of our analytics, and that’s made a huge difference for us as we grow.
In this post I’ll walk through our design, and how you can use the same approach to iterate rapidly and safely for your customers wherever they are. The system, which we call the Frame Analytics Build System (FABS), is a combination of Python, Jinja2, and Git automation.
(1) Anonymized example of customer analytics dashboards from Frame.
Frame for Slack is highly configurable, allowing every team to align Frame’s conversation enhancements with their existing tools and processes. Configurability and easy iteration are built into the engine that handles our operational logic, and I wanted our analytics products to have all of those same great qualities.
Having built customer-facing reporting products before I knew they can seem straightforward, but often require several iterations to get right. Traditionally, I would have assembled a team of UX, design, front-end, and back-end engineering skillsets to build a reporting webapp for our customers, but this approach is both slow and resource intensive.
In search of an agile alternative, I turned to Looker’s embedded analytics capabilities. I knew if I could leverage Looker’s data modeling, permissioning, and visualization capabilities in a way that provided the kinds of production guarantees we needed for our customers, we would be able to move exceptionally fast in bringing new analytics products to market.
I needed a way to guarantee the following:
Looker doesn’t have all of these features out of the box, but because it exposes all data models and visual artifacts in code (LookML), adding the missing pieces was easy. And because the Looker API can render these artifacts, it’s straightforward to build automated tooling around them. Enter: FABS.
(2) Anonymized example of Frame’s embedded Operational Dashboard
FABS takes a customer configuration file and a set of core Looker view files and renders the full set of LookML files required to fully specify a reporting product for a customer (view, model, dashboard files). The final dashboards are then embedded in our management console and made available to Frame’s enterprise customers (example shown above). Importantly, all core views are versioned when referenced in a deploy, so ALL files that define a single customer’s reporting are effectively immutable. You can see the resulting LookerML structure diagrammed for two customers below:
(3) Example FABS Looker architecture
Core views define the “baseline” for our analytics features in this hub and spoke model, and each configuration file defines the transformations and extensions required to create a single tailored spoke. By separating definition and deployment, we decouple customer applications from each other as well as from any previous versions of themselves. Since rendering the final configuration to any spoke is programmatic, it becomes trivial to specify and (re)generate an arbitrary number of them.
There are a few pretty magical things happening above.
(4) FABS viewed through the lense of version control
Mechanically, FABS is a mix of Python and Jinja2 templates. We specify high-level model, view, and dashboard configurations using YAML, defining overrides of any dimension, measure, or dashboard as needed. You can see a toy example below:
(5) a toy example of a single customer config YAML
In the above example, we customize how a customer name is presented in reports by overriding the display name and provide custom drill downs for customers in the orders view. Additionally, we define the required joins for the model and include a “Customer Retention” dashboard from our reports library (also YAML) to be deployed.
Once we’ve used FABS to generate the appropriate LookML files, we push them to a development branch of a Looker Git repository. A simple refresh of the Looker developer GUI detects a remote update to that development branch, prompting us pull the recently deployed LookML updates into Looker’s developer mode. Here we can run LookML and content validation, and spot check any updated dashboards for correctness before a final customer-facing deploy.
(6) Rendering from a config YAML to LookML files
Taken all together, FABS and Looker allows Frame to provide our customers a high-quality analytics product in a way that is scalable for us and exceptionally responsive and tailored for them. While we are using this system to deploy for external customers, one could easily imagine using the system to deploy for internal customers at large organizations.
Analytic reporting is just one of the many data problems we are solving here at Frame. If you are excited by building or using cutting edge conversational AI please reach us at email@example.com or, even better, install our Slack app and DM us directly!