Build a Simple Looker Micro Frontend with Streamlit and Looker SDK

Michaël Scherding
5 min readFeb 26, 2023

--

Hey 👋

Hope you’re doing great!

In this article, we’ll build a simple Looker micro frontend using Streamlit and the Looker SDK. A Looker micro frontend is a small, custom-built application that allows users to interact with Looker content without having to navigate the Looker interface or having to share admin access. In this example, we’ll build a micro frontend that allows users to manage users and datagroups. But of course, you can go deeper.

To get started, make sure you have Python installed and create a new virtual environment. Then, install the necessary libraries:

pip install streamlit pandas looker-sdk

Next, create a new Python file and import the necessary libraries:

import os
import streamlit as st
import pandas as pd
import looker_sdk
from looker_sdk import models40

The os library is used to set environment variables for the Looker SDK, while streamlit is the web framework we'll be using. pandas is used to work with tabular data, and looker_sdk is the official Looker SDK for Python.

We’ll set the Looker SDK environment variables using GitHub secrets. If you’re not familiar with GitHub secrets, they allow you to store and encrypt sensitive information in your GitHub repository. With streamlit you will have to encrypt with toml file.

os.environ["LOOKERSDK_BASE_URL"] = "https://mylookerinstance.eu.looker.com/"
os.environ["LOOKERSDK_API_VERSION"] = "4.0"
os.environ["LOOKERSDK_VERIFY_SSL"] = "true"
os.environ["LOOKERSDK_TIMEOUT"] = "120"
os.environ["LOOKERSDK_CLIENT_ID"] = "client_id"
os.environ["LOOKERSDK_CLIENT_SECRET"] = "client_secret"

Replace mylookerinstance with the name of your Looker instance, and replace client_id and client_secret with your Looker API credentials.

Next, we define the main function, which is where we’ll build our micro frontend.

def main():
st.header("My Looker Micro Front")
st.markdown("---")

This sets the header and adds a markdown divider.

Next, we’ll add a section for managing users. We’ll start by authenticating with the Looker SDK.

    # Authenticate with Looker SDK
sdk = looker_sdk.init31() # or looker_sdk.init40()

We’ll define a collapsible section for adding users to groups.

    user_management_expander = st.expander("Add Users to Groups", expanded=False)
with user_management_expander:

Inside the expander, we’ll call the Looker SDK to get all users.

        # Call Looker SDK to get all users
all_users = sdk.all_users()
user_info = []
for user in all_users:
user_info.append({
"ID": user.id,
"Email": user.email,
"First Name": user.first_name,
"Last Name": user.last_name,
"Disabled": user.is_disabled
})

We’ll display all users in a table with checkboxes to select users.

        # Display all users in a table with checkboxes to select users
user_info_df = pd.DataFrame(user_info)
user_info_df['Option'] = user_info_df['ID'].astype(str) + ' - ' + user_info_df['First Name'] + ' ' + user_info_df['Last Name'] + ' (' + user_info_df['Email'] + ')'
selected_user_options = user_info_df.set_index('ID')['Option'].to_dict()
selected_user_ids = st.multiselect("Select users to add to groups", options=list

Then you will have to play with groups:

# Call Looker SDK to get all groups
all_groups = sdk.all_groups()
group_info = []
for group in all_groups:
group_info.append({
"ID": group.id,
"Name": group.name,
"User Count": group.user_count
})

# Display all groups in a table with checkboxes to select groups
group_info_df = pd.DataFrame(group_info)
group_info_df['Option'] = group_info_df['ID'].astype(str) + ' - ' + group_info_df['Name']
selected_group_options = group_info_df.set_index('ID')['Option'].to_dict()
selected_group_ids = st.multiselect("Select groups to add users to", options=list(selected_group_options.keys()), format_func=lambda x: selected_group_options[x])
selected_groups_df = group_info_df[group_info_df['ID'].isin(selected_group_ids)]
st.dataframe(selected_groups_df)

The Looker SDK is used to retrieve a list of all groups available. Then, the group information is stored in a list of dictionaries group_info that contains the group ID, name and user count.

Next, a pandas DataFrame group_info_df is created from the group_info list. In this DataFrame, a new column 'Option' is added, which concatenates the group ID and name as a single string. This concatenated string is used to identify each group in the UI.

st.multiselect() is used to display a multiselect widget in the Streamlit app that shows all the available groups in a dropdown. The format_func parameter is used to display the group names and IDs as labels in the dropdown. When the user selects one or more groups, the selected group IDs are stored in selected_group_ids.

Finally, the code filters the group_info_df to display only the selected groups in a pandas DataFrame selected_groups_df. The selected groups are then displayed to the user in a table using st.dataframe().

This code block is responsible for adding selected users to selected groups.

if st.button("Add Users to Selected Groups"):
if len(selected_user_ids) == 0 or len(selected_group_ids) == 0:
st.warning("Please select at least one user and one group.")
else:
# Call Looker SDK to add users to groups
for group_id in selected_group_ids:
for user_id in selected_user_ids:
sdk.add_group_user(group_id=group_id, body=models40.GroupIdForGroupUserInclusion(user_id=user_id))
st.success(f"Selected users ({len(selected_user_ids)}) added to selected groups ({len(selected_group_ids)}).")

This code block creates a button “Add Users to Selected Groups” in the Streamlit app, and when clicked, it first checks if both selected_user_ids and selected_group_ids lists are not empty. If at least one of them is empty, it shows a warning message "Please select at least one user and one group.".

If both selected_user_ids and selected_group_ids lists are not empty, the code block then calls Looker SDK to add the selected users to the selected groups. It does this using a nested loop, where it loops through each selected group and for each group, it loops through each selected user and calls the Looker SDK method add_group_user() with the selected group_id and user_id as parameters.

Once the users are added to the groups, it shows a success message that shows the number of selected users and selected groups that were added. The message is shown using the st.success() function.

In conclusion, Streamlit is a great tool for Python developers because it allows them to easily create and deploy interactive web applications without having to learn web development. Streamlit provides a simple syntax that enables developers to focus on their code, making it easy to prototype and iterate on their ideas. With Streamlit, developers can create data visualizations, machine learning models, and more, all in a few lines of code. This makes Streamlit an excellent choice for anyone looking to quickly and easily build and share Python-based applications.

You can find the full code available here.

Have fun 🤟

--

--