[docs]classAuthorisationError(Exception):"""Indicates that the authorisation permanently went wrong."""pass
[docs]classIdentityProvider:"""Class for interfacing with the IdentityProvider."""def__init__(self,well_known_endpoint:str):self._well_known_endpoint=well_known_endpointself._token_endpoint,self._device_endpoint=self._get_endpoints()self._headers={"Content-Type":"application/x-www-form-urlencoded"}def_get_endpoints(self)->Tuple[str,str]:response=requests.get(self._well_known_endpoint)response.raise_for_status()config=response.json()returnconfig["token_endpoint"],config["device_authorization_endpoint"]
[docs]classOauthDeviceSession:"""Class for storing OAuth session information and refreshing tokens when needed."""def__init__(self,host:Url,settings:ApiSettings,identity_provider:IdentityProvider):self._api_settings=settings_auth_settings=settings.auths[host]self._host=hostself._client_id=_auth_settings.client_idself._token_info=_auth_settings.tokensself._refresh_time_reduction=5# the number of seconds to refresh the expiration timeself._identity_provider=identity_provider
[docs]defrefresh(self)->TokenInfo:ifself._token_infoisNone:raiseAuthorisationError("You should authenticate first before you can refresh")ifself._token_info.access_expires_at>time.time()+self._refresh_time_reduction:returnself._token_infotry:self._token_info=TokenInfo(**self._identity_provider.refresh_access_token(self._client_id,self._token_info.refresh_token))self._api_settings.store_tokens(self._host,self._token_info)returnself._token_infoexceptrequests.HTTPErrorase:raiseAuthorisationError(f"An error occurred during token refresh: {e}")