streamlit-oauth

repository·main·Indexed 42 days ago

https://github.com/dnplus/streamlit-oauth

A wrapper around httpx_oauth designed to simplify the integration of OAuth2 authorization flows into Streamlit data applications. It provides the OAuth2Component for managing authorization buttons, token refreshing, and token revocation.

Tokens
2.2K
Snippets
7
Records
8
Agent score
3%

What's inside streamlit-oauth

  1. How the OAuth2 flow returns data to Streamlit

    main

    The component manages the OAuth2 flow using a popup window. The process works as follows:

    1. The component opens the authorization_url in a new popup window.
    2. It monitors the popup's URL via a polling interval.
    3. It waits for the popup to redirect to the specified redirect_uri (extracted from the authorization_url).
    4. Once the redirect is detected, the component extracts all URL query parameters from the popup's new location.
    5. The component closes the popup and sends the resulting key-value pairs back to Streamlit using Streamlit.setComponentValue(qs).

    Note on Security: The component handles SecurityError exceptions during polling, which typically occur due to cross-origin restrictions while the popup is navigating. It ignores these errors and continues waiting until the redirect is complete.

  2. Complete OAuth2 Integration Example

    main

    This pattern demonstrates the standard lifecycle of an OAuth2 session in Streamlit: loading credentials, checking for an existing token in st.session_state, showing an authorization button if missing, and providing a refresh mechanism if the token is present.

    import streamlit as st
    from streamlit_oauth import OAuth2Component
    import os
    from dotenv import load_dotenv
    
    load_dotenv()
    
    AUTHORIZE_URL = os.environ.get('AUTHORIZE_URL')
    TOKEN_URL = os.environ.get('TOKEN_URL')
    REFRESH_TOKEN_URL = os.environ.get('REFRESH_TOKEN_URL')
    REVOKE_TOKEN_URL = os.environ.get('REVOKE_TOKEN_URL')
    CLIENT_ID = os.environ.get('CLIENT_ID')
    CLIENT_SECRET = os.environ.get('CLIENT_SECRET')
    REDIRECT_URI = os.environ.get('REDIRECT_URI')
    SCOPE = os.environ.get('SCOPE')
    
    oauth2 = OAuth2Component(CLIENT_ID, CLIENT_SECRET, AUTHORIZE_URL, TOKEN_URL, REFRESH_TOKEN_URL, REVOKE_TOKEN_URL)
    
    if 'token' not in st.session_state:
        result = oauth2.authorize_button("Authorize", REDIRECT_URI, SCOPE)
        if result and 'token' in result:
            st.session_state.token = result.get('token')
            st.rerun()
    else:
        token = st.session_state['token']
        st.json(token)
        if st.button("Refresh Token"):
            token = oauth2.refresh_token(token)
            st.session_state.token = token
            st.rerun()
  3. Initialize OAuth2Component

    main

    To use Streamlit OAuth, create an instance of OAuth2Component by providing your client credentials and the various OAuth2 server endpoints.

    Important: Ensure your OAuth2 provider's callback URL is set to https://<YOUR ADDRESS>/component/streamlit_oauth.authorize_button.

    from streamlit_oauth import OAuth2Component
    import os
    
    # Example initialization using environment variables
    oauth2 = OAuth2Component(
        client_id=os.environ.get('CLIENT_ID'),
        client_secret=os.environ.get('CLIENT_SECRET'),
        authorize_endpoint=os.environ.get('AUTHORIZE_URL'),
        token_endpoint=os.environ.get('TOKEN_URL'),
        refresh_token_endpoint=os.environ.get('REFRESH_TOKEN_URL'),
        revoke_token_endpoint=os.environ.get('REVOKE_TOKEN_URL')
    )
  4. Use revoke_token() to invalidate tokens

    main

    The revoke_token method is used to revoke an existing token.

    Parameters:

    • token: The token object to be revoked.
    • token_type_hint: A hint about the type of token being submitted (e.g., 'access_token').

    Returns: A boolean indicating whether the revocation was successful.

    # Example usage
    success = oauth2.revoke_token(st.session_state.token)
  5. Use authorize_button() to start the OAuth2 flow

    main

    The authorize_button method generates an HTML button that initiates the OAuth2 authorization code grant flow. When clicked, it opens a popup window for the user to authorize the application.

    Parameters:

    • name: The label displayed on the button.
    • redirect_uri: The URL where the server redirects the user after authorization.
    • scope: The required OAuth2 scopes.
    • height / width: Dimensions of the popup window.
    • key: Unique key for the component.
    • extra_params: Dictionary of additional parameters for the authorization server.
    • pkce: Set to 'S256' to use Proof Key for Code Exchange.
    • use_container_width: If True, the button expands to the container width.
    • icon: Icon to display on the button.
    • auto_click: If True, the button is clicked automatically.

    Returns: A dictionary containing the authorization code or access token object.

    # Example usage within a Streamlit app
    result = oauth2.authorize_button("Authorize", REDIRECT_URI, SCOPE)
    if result and 'token' in result:
        st.session_state.token = result.get('token')
        st.rerun()
  6. Use refresh_token() to update access tokens

    main

    The refresh_token method uses the existing refresh token to obtain a new access token. If the current token is still valid (not expired), it returns the same token.

    Parameters:

    • token: The current access token object.
    • force: Boolean. If True, forces the refresh even if the access token is not expired.

    Returns: A dictionary containing the new access token or the existing one if not expired.

    # Example usage to refresh a token stored in session state
    if st.button("Refresh Token"):
        new_token = oauth2.refresh_token(st.session_state.token)
        st.session_state.token = new_token
        st.rerun()
  7. Configure the OAuth2Component arguments

    main

    The frontend component receives configuration via the args object during the onRender event. When using the OAuth2Component in Streamlit, you can pass the following parameters to customize the widget's behavior and appearance:

    • authorization_url (Required): The URL to which the user is redirected for OAuth2 authorization.
    • name (String): The text displayed on the authorization button (e.g., "AUTHORIZE").
    • popup_width (Number): The width of the popup window used for the OAuth flow.
    • popup_height (Number): The height of the popup window used for the OAuth flow.
    • icon (String): A URL to an image to be used as the button icon. If not provided, the icon space is collapsed.
    • use_container_width (Boolean): If true, the button will expand to fill 100% of the container width.
    • auto_click (Boolean): If true, the component will attempt to trigger the button click automatically upon rendering (useful for seamless flows).
    // Example structure of the args object passed from Python
    {
      "authorization_url": "https://example.com/oauth/authorize",
      "name": "Login with Google",
      "popup_width": 500,
      "popup_height": 600,
      "icon": "https://example.com/icon.png",
      "use_container_width": true,
      "auto_click": false
    }