diff --git a/.changeset/wise-moments-agree.md b/.changeset/wise-moments-agree.md new file mode 100644 index 000000000000..b8238b00e739 --- /dev/null +++ b/.changeset/wise-moments-agree.md @@ -0,0 +1,5 @@ +--- +"gradio": minor +--- + +feat:Single oauth button diff --git a/gradio/components/login_button.py b/gradio/components/login_button.py index 98ebc1d060af..b091bec5ee68 100644 --- a/gradio/components/login_button.py +++ b/gradio/components/login_button.py @@ -1,6 +1,7 @@ """Predefined button to sign in with Hugging Face in a Gradio Space.""" from __future__ import annotations +import json import warnings from typing import Literal @@ -24,7 +25,7 @@ class LoginButton(Button): def __init__( self, value: str = "Sign in with Hugging Face", - signed_in_value: str = "Signed in as {}", + logout_value: str = "Logout ({})", *, every: float | None = None, variant: Literal["primary", "secondary", "stop"] = "secondary", @@ -39,14 +40,17 @@ def __init__( render: bool = True, scale: int | None = 0, min_width: int | None = None, + signed_in_value: str = "Signed in as {}", ): """ Parameters: - signed_in_value: The text to display when the user is signed in. The string should contain a placeholder for the username, e.g. "Signed in as {}". + logout_value: The text to display when the user is signed in. The string should contain a placeholder for the username with a call-to-action to logout, e.g. "Logout ({})". """ - if signed_in_value is None: - signed_in_value = "Signed in as {}" - self.signed_in_value = signed_in_value + if signed_in_value != "Signed in as {}": + warnings.warn( + "The `signed_in_value` parameter is deprecated. Please use `logout_value` instead." + ) + self.logout_value = logout_value super().__init__( value, every=every, @@ -73,7 +77,10 @@ def activate(self): # Taken from https://cmgdo.com/external-link-in-gradio-button/ # Taking `self` as input to check if user is logged in # ('self' value will be either "Sign in with Hugging Face" or "Signed in as ...") - self.click(fn=None, inputs=[self], outputs=None, js=_js_open_if_not_logged_in) + _js = _js_handle_redirect.replace( + "BUTTON_DEFAULT_VALUE", json.dumps(self.value) + ) + self.click(fn=None, inputs=[self], outputs=None, js=_js) self.attach_load_event(self._check_login_status, None) @@ -86,21 +93,24 @@ def _check_login_status(self, request: Request) -> LoginButton: return LoginButton(value=self.value, interactive=True) else: username = session["oauth_info"]["userinfo"]["preferred_username"] - signed_in_text = self.signed_in_value.format(username) - return LoginButton(signed_in_text, interactive=False) + logout_text = self.logout_value.format(username) + return LoginButton(logout_text, interactive=True) # JS code to redirects to /login/huggingface if user is not logged in. # If the app is opened in an iframe, open the login page in a new tab. # Otherwise, redirects locally. Taken from https://stackoverflow.com/a/61596084. -_js_open_if_not_logged_in = """ +# If user is logged in, redirect to logout page (always in-place). +_js_handle_redirect = """ (buttonValue) => { - if (!buttonValue.includes("Signed in")) { + if (buttonValue === BUTTON_DEFAULT_VALUE) { if ( window !== window.parent ) { window.open('/login/huggingface', '_blank'); } else { window.location.assign('/login/huggingface'); } + } else { + window.location.assign('/logout'); } } """ diff --git a/gradio/components/logout_button.py b/gradio/components/logout_button.py index 1fd59c670537..c80822e0e001 100644 --- a/gradio/components/logout_button.py +++ b/gradio/components/logout_button.py @@ -1,6 +1,7 @@ """Predefined button to sign out from Hugging Face in a Gradio Space.""" from __future__ import annotations +import warnings from typing import Literal from gradio_client.documentation import document, set_documentation_group @@ -14,6 +15,9 @@ class LogoutButton(Button): """ Button to log out a user from a Space. + + Note: `LogoutButton` component is deprecated. Please use `gr.LoginButton` instead + which handles both the login and logout processes. """ is_template = True @@ -37,6 +41,9 @@ def __init__( scale: int | None = 0, min_width: int | None = None, ): + warnings.warn( + "The `gr.LogoutButton` component is deprecated. Please use `gr.LoginButton` instead which handles both the login and logout processes." + ) super().__init__( value, every=every,