Streamlit¶
The SDK includes a Streamlit helper for building interactive web apps on SweatStack. It needs the optional streamlit extra:
uv add "sweatstack[streamlit]"
Register an application in your SweatStack account at app.sweatstack.no/settings/api and create a secret for it. See Setup.
Then use the StreamlitAuth component to authenticate your users:
import streamlit as st
from sweatstack.streamlit import StreamlitAuth
# Initialize the authentication component
auth = StreamlitAuth(
client_id="YOUR_APPLICATION_ID",
client_secret="YOUR_APPLICATION_SECRET",
redirect_uri="http://localhost:8501",
)
# Render the login or logout button (in the sidebar, in this case)
with st.sidebar:
auth.authenticate()
# Stop here for users who are not signed in
if not auth.is_authenticated():
st.write("Please log in to continue")
st.stop()
# The user is signed in: use the client
st.write("Welcome to SweatStack")
latest_activity = auth.client.activities.latest()
st.write(f"Latest activity: {latest_activity.sport} on {latest_activity.start}")
# A selectbox to switch between the users this user has access to
with st.sidebar:
auth.select_user()
Use auth.client, not the module-level interface
In a Streamlit app you cannot use the module-level interface (sweatstack.activities.list(), sweatstack.profile.sports(), and so on). It shares one client across every Streamlit session, so it can leak data between users. Make every request through the Client at auth.client, or through one of the widgets below.
redirect_uri
The redirect_uri is the URL of your Streamlit application. For local development, this is http://localhost:8501. Update it when you deploy the app, and register the deployed URL on your application in your SweatStack account.
Widgets and methods¶
Besides authenticate(), is_authenticated() and client, StreamlitAuth offers:
auth.logout_button(): renders a logout button.auth.select_user(): a selectbox to switch to another user this user has access to.auth.clientthen acts as the selected user.auth.switch_to_principal_user(): switchauth.clientback to the signed-in user.auth.select_activity(): a selectbox of the user's recent activities. Returns the selected activity.auth.select_sport(),auth.select_tag(),auth.select_metric(): selectboxes for a sport, a tag, or a metric.auth.get_authorization_url(): the OAuth2 authorization URL, if you render your own login link.
StreamlitAuth reference¶
Handles SweatStack authentication and provides UI components for Streamlit apps.
This class manages OAuth2 authentication flow for Streamlit applications and provides convenient selector components for activities, sports, tags, and metrics. Once authenticated, the client property provides access to the SweatStack API.
Example
import streamlit as st from sweatstack.streamlit import StreamlitAuth
Initialize authentication¶
auth = StreamlitAuth( client_id="YOUR_APPLICATION_ID", client_secret="YOUR_APPLICATION_SECRET", redirect_uri="http://localhost:8501", )
Add authentication to sidebar¶
with st.sidebar: auth.authenticate()
Check authentication¶
if not auth.is_authenticated(): st.write("Please log in to continue") st.stop()
Use the authenticated client¶
st.write("Welcome to SweatStack") latest_activity = auth.client.activities.latest() st.write(f"Latest activity: {latest_activity.sport} on {latest_activity.start_local}")
Switch between accessible users (admin feature)¶
with st.sidebar: auth.select_user()
Attributes:
-
client–The SweatStack Client instance for API access.
-
api_key–The current API access token.
__init__(client_id=None, client_secret=None, scopes=None, redirect_uri=None)
¶
Initialize the StreamlitAuth component.
Parameters:
-
client_id(str | None, default:None) –OAuth2 client ID. Falls back to SWEATSTACK_CLIENT_ID env var.
-
client_secret(str | None, default:None) –OAuth2 client secret. Falls back to SWEATSTACK_CLIENT_SECRET env var.
-
scopes(list[str | Scope] | None, default:None) –OAuth2 scopes. Falls back to SWEATSTACK_SCOPES env var. Defaults to data:read, profile.
-
redirect_uri(str | None, default:None) –OAuth2 redirect URI. Falls back to SWEATSTACK_REDIRECT_URI env var.
authenticate(login_label=None, show_logout=True)
¶
Authenticates the user with SweatStack.
This method handles the authentication flow for SweatStack in a Streamlit app. It checks if the user is already authenticated, and if not, displays a login button. If the user is authenticated, it displays a logout button.
When the user clicks the login button, they are redirected to the SweatStack authorization page. After successful authorization, they are redirected back to the Streamlit app with an authorization code, which is exchanged for an access token.
In proxy mode, this method only shows the login button if not authenticated. The proxy handles the OAuth callback and token exchange.
Parameters:
-
login_label(str | None, default:None) –The label to display on the login button. Defaults to "Login with SweatStack".
behind_proxy(redirect_uri, header_name='X-SweatStack-Token', logout_uri='/logout', login_uri='/login')
classmethod
¶
Create a StreamlitAuth instance for use behind a proxy.
Use this method when your Streamlit app runs behind a proxy that handles authentication and passes the SweatStack access token via an HTTP header.
Parameters:
-
redirect_uri(str) –The URI to redirect to after login (used by proxy).
-
header_name(str, default:'X-SweatStack-Token') –The HTTP header name containing the access token. Defaults to "X-SweatStack-Token".
-
logout_uri(str, default:'/logout') –The URI to redirect to for logout. Defaults to "/logout".
-
login_uri(str, default:'/login') –The URI to redirect to for login. Defaults to "/login".
Returns:
-
StreamlitAuth(StreamlitAuth) –An instance configured for proxy mode.
Example
auth = StreamlitAuth.behind_proxy( redirect_uri="https://myapp.example.com/app", )
if not auth.is_authenticated(): st.error("Missing authentication header") st.stop()
activities = auth.client.activities.list()
get_authorization_url()
¶
Generates the OAuth2 authorization URL for SweatStack.
This method constructs the URL users will be redirected to for OAuth2 authorization. It includes the client ID, redirect URI, scopes, and other OAuth2 parameters.
Returns:
-
str(str) –The complete authorization URL.
is_authenticated()
¶
Checks if the user is currently authenticated with SweatStack.
This method determines if the user has a valid API key stored in the session state or in the instance. It does not verify if the API key is still valid with the server.
Returns:
-
bool(bool) –True if the user has an API key, False otherwise.
logout_button()
¶
Displays a logout button and handles user logout.
In standard mode, clears the stored API key from session state, resets the client, and triggers a Streamlit rerun.
In proxy mode, displays a styled link that redirects to the logout URI.
select_activity(*, start=None, end=None, sport=None, tags=None, limit=100)
¶
Select an activity from the user's activities.
This method retrieves activities based on specified filters and displays them in a dropdown for selection.
Parameters:
-
start(date | None, default:None) –Optional start date to filter activities.
-
end(date | None, default:None) –Optional end date to filter activities.
-
sport(Sport | str | list[Sport | str] | None, default:None) –One sport or a list; an activity matches any of them.
-
tags(str | list[str] | None, default:None) –One tag or a list; an activity must have all of them.
-
limit(int, default:100) –Maximum number of activities to retrieve. Defaults to 100.
Returns:
-
ActivitySummary(ActivitySummary) –The selected activity.
Note
Activities are displayed in the format "YYYY-MM-DD sport_name".
select_metric(allow_multiple=False)
¶
Select a metric from the available metrics.
This method displays metrics in a dropdown or multiselect for selection.
Parameters:
-
allow_multiple(bool, default:False) –If True, allows selecting multiple metrics. Defaults to False.
Returns:
select_sport(only_root=False, allow_multiple=False, only_available=True)
¶
Select a sport from the available sports.
This method retrieves sports and displays them in a dropdown or multiselect for selection.
Parameters:
-
only_root(bool, default:False) –If True, only returns root sports without parents. Defaults to False.
-
allow_multiple(bool, default:False) –If True, allows selecting multiple sports. Defaults to False.
-
only_available(bool, default:True) –If True, only shows sports available to the user. If False, shows all standard OpenSportTaxonomy sports. Defaults to True.
Returns:
-
Sport | list[Sport]–Sport | list[Sport]: The selected sport, or sports if
allow_multiple.
Note
Sports are displayed in a human-readable format using each sport's label.
select_tag(allow_multiple=False)
¶
Select a tag from the available tags.
This method retrieves tags and displays them in a dropdown or multiselect for selection.
Parameters:
-
allow_multiple(bool, default:False) –If True, allows selecting multiple tags. Defaults to False.
Returns:
-
str | list[str]–str | list[str]: The selected tag, or tags if
allow_multiple.
Note
Empty tags are displayed as "-" in the dropdown.
select_user(*, team_id=None)
¶
Displays a user selection dropdown; auth.client then acts as the selected user.
Lists the users the signed-in (principal) user can access and replaces auth.client
with a client delegated to the selected one. The session keeps that user's access and
refresh tokens together, so a token refresh never falls back to the principal.
Parameters:
-
team_id(str | None, default:None) –Optional team ID. When provided, delegates via team membership instead of direct user permissions.
Returns:
-
UserSummary(UserSummary) –The selected user object.
Note
This method requires the user to have appropriate permissions to access other users. For regular users, this typically only shows their own user information.
switch_to_principal_user()
¶
Switches the client back to the principal user.
This method reverts the client's authentication from a delegated user back to the principal user. The client will use the principal token for all subsequent API calls and updates the session state with the new API key.
Raises:
-
SweatStackAPIError–If the principal token request fails.