In this article, I will show you how to build a Streamlit Component to authenticate users in Streamlit applications and external APIs with Auth0.
TL;DR: If you've built a Streamlit application and must share it securely with an external or internal audience, you'll need to add user authentication features. If your Streamlit application must access secure APIs, you'll need a way to authorize access. In my previous article, Introduction to Streamlit and Streamlit Components, you learned how to extend Streamlit's functionality using its component API, and you built both simple and moderately complex custom Streamlit components. The idea was to equip you with knowledge of a component design that will make it easy now to use Auth0 authentication in Streamlit. My experience with Streamlit can be verified on the official page of Streamlit Creators, and in this article, I will show you in detail exactly how to do that.
Introduction
In the Introduction to Streamlit and Streamlit Components, you learned that Streamlit Components have two parts, namely:
- A frontend is implemented in any web technology you prefer (JavaScript, React, Vue, etc.) and gets rendered in Streamlit apps via an
iframe
tag. - A Python API which Streamlit client apps use to instantiate the frontend and communicate with it. This API is exposed via the
streamlit.components.v1.declare_component
object.
In the previous article, we built Component Hero using the Next.js web framework, which in theory allows us to implement nice user experiences with the server-side rendering of static web pages and host API endpoints. I won't build a fancy UI to interact with Auth0 login, but I will use the self-hosted API functionality of Next.js.
The primary purpose of Component Hero is to wrap the core Streamlit components API adding support for passing events (structured objects) between the frontend and Streamlit and handling errors. In this article, we're going to use the same design as Component Hero to build Component Auth0.
Authentication Component Using Auth0
Let's go into the details of building Component Auth0 integrating Auth0 authentication in Streamlit applications and using its identity and access token credentials to invoke protected Streamlit Python functions and protected external APIs.
Before we proceed, let me remind you of some important terminology. The Component Auth0 Python wrapper, which hosts the Streamlit component, will be referred to as component host or Streamlit host and the Streamlit code for the rest of the application as Streamlit client. The component implementation will be called component frontend or simply frontend.
Component Auth0 application demo
This little demonstration gives you an idea of the final goal we will achieve:
Capabilities
The diagram below shows what will be implemented. The main takeaway is that the Streamlit app server and frontend webserver run as two separate server-based applications. The component implementation cannot be run in Streamlit's server, so it must be executed in its own process and web server. I run Streamlit locally on port 4010 and the frontend locally on port 3001. You can do the same to make it easier to reuse the code and follow the design.
Architecture
The architecture view captures the relationships between the capabilities, shedding light on how the application works.
Application start-up sequence
Since this component is fairly complicated, I have a sequence diagram showing the interactions between capabilities, which will help you better follow the code further below.
Component Auth0 implementation details
Now's a good time to download the GitHub repository for this article. Navigate to folder ./article-2/code/auth0/
. The code snippets that will be shown in the following sections have been abbreviated a little and will not run on their own.
There are three parts to the Component Auth0 application, which I will explain in some detail:
- The Streamlit component host: a Python wrapper class and an event handler function (embedded in the Streamlit client application)
- The component: a Next.js (React) web app implementing the component (runs on localhost, port 3001)
- The Streamlit client application (runs on localhost, port 4010)
The implementation of these parts is similar to the corresponding parts of Component Hero described in the previous article.
In addition, complementing the application, a standalone service hosts protected API endpoints:
- The Remote APIs service: a Flask server hosting remote/external APIs (runs on localhost, port 8888)
Please refer to the diagrams of the system capabilities and system architecture above as you read the code sections below. In this way, you will have enough detail to replicate the code and make changes to the design and implementation yourself.
Top comments (0)