Skip to content

Albert SSO Client

albert.AlbertSSOClient

Bases: BaseAlbertModel, AuthManager

OAuth2 client for performing Authorization Code Flow with the Albert API.

This client opens a browser-based SSO login flow and handles token acquisition and refresh using a local redirect server.

If base_url is not provided, it defaults to the value of the environment variable ALBERT_BASE_URL or https://app.albertinvent.com.

Important

You must call .authenticate() before passing this client to Albert(auth_manager=...) to ensure the token is acquired and ready for use.

Attributes:

Name Type Description
base_url str

The base URL of the Albert API.

email str

The email address used for initiating the login flow.

Usage
oauth = AlbertSSOClient(
    email="user@example.com",
)
oauth.authenticate()
client = Albert(auth_manager=oauth)
client.roles.get_all()
Show JSON schema:
{
  "description": "OAuth2 client for performing Authorization Code Flow with the Albert API.\n\nThis client opens a browser-based SSO login flow and handles token acquisition\nand refresh using a local redirect server.\n\nIf `base_url` is not provided, it defaults to the value of the environment\nvariable `ALBERT_BASE_URL` or `https://app.albertinvent.com`.\n\n!!! important\n    You **must call** `.authenticate()` before passing this client to `Albert(auth_manager=...)`\n    to ensure the token is acquired and ready for use.\n\nAttributes\n----------\nbase_url : str\n    The base URL of the Albert API.\nemail : str\n    The email address used for initiating the login flow.\n\nUsage\n-----\n```\noauth = AlbertSSOClient(\n    email=\"user@example.com\",\n)\noauth.authenticate()\nclient = Albert(auth_manager=oauth)\nclient.roles.get_all()\n```",
  "properties": {
    "base_url": {
      "title": "Base Url",
      "type": "string"
    },
    "email": {
      "title": "Email",
      "type": "string"
    }
  },
  "required": [
    "email"
  ],
  "title": "AlbertSSOClient",
  "type": "object"
}

Fields:

base_url

base_url: str

email

email: str

refresh_token_url

refresh_token_url: str

authenticate

authenticate(
    minimum_port: int = 5000,
    maximum_port: int | None = None,
    tenant_id: str | None = None,
    timeout: int = 5,
) -> OAuthTokenInfo

Launch an interactive browser-based SSO login and return an OAuth token.

This method starts a temporary local HTTP server, opens the SSO login URL in the default browser, and waits for the authentication redirect to capture the refresh token.

Parameters:

Name Type Description Default
minimum_port int

The starting port to attempt for the local HTTP redirect server (default is 5000).

5000
maximum_port int | None

The maximum port to try if the minimum_port is unavailable. If None, only the minimum port will be tried.

None
tenant_id str | None

Optional tenant ID to scope the SSO login request.

None

Returns:

Type Description
OAuthTokenInfo

The initial token info containing the refresh token.

Source code in src/albert/core/auth/sso.py
def authenticate(
    self,
    minimum_port: int = 5000,
    maximum_port: int | None = None,
    tenant_id: str | None = None,
    timeout: int = 5,
) -> OAuthTokenInfo:
    """
    Launch an interactive browser-based SSO login and return an OAuth token.

    This method starts a temporary local HTTP server, opens the SSO login URL
    in the default browser, and waits for the authentication redirect to capture
    the refresh token.

    Parameters
    ----------
    minimum_port : int, optional
        The starting port to attempt for the local HTTP redirect server (default is 5000).
    maximum_port : int | None, optional
        The maximum port to try if the `minimum_port` is unavailable. If None, only the
        minimum port will be tried.
    tenant_id : str | None, optional
        Optional tenant ID to scope the SSO login request.

    Returns
    -------
    OAuthTokenInfo
        The initial token info containing the refresh token.
    """
    self._validate_email(email=self.email, tenant_id=tenant_id)
    with local_http_server(
        minimum_port=minimum_port,
        maximum_port=maximum_port,
        timeout=timeout,
    ) as (server, port):
        login_url = self._build_login_url(port=port, tenant_id=tenant_id)
        webbrowser.open(login_url)
        # Block here until one request arrives at localhost:port/?token=…
        server.handle_request()
        refresh_token = server.token
        if not refresh_token:
            raise AlbertAuthError("SSO Login failed! Please try again.")

    self._token_info = OAuthTokenInfo(
        refresh_token=refresh_token,
        tenant_id=tenant_id.upper() if tenant_id else None,
    )
    return self._token_info

get_access_token

get_access_token() -> str

Return a valid access token, refreshing it if needed.

Source code in src/albert/core/auth/sso.py
def get_access_token(self) -> str:
    """Return a valid access token, refreshing it if needed."""
    if not self._token_info or not self._token_info.refresh_token:
        raise AlbertAuthError("Client not authenticated. Call `.authenticate()` first.")
    if self._requires_refresh():
        self._request_access_token()
    return self._token_info.access_token