diff --git a/CHANGELOG.md b/CHANGELOG.md index af707a9..c5a9ed6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 0.9.27 (2026-01-14) + +### Changes + +- When a request response is 401 Unauthorized and a JSON Web Token was used for the request, clear the token and retry the request to fetch a new token via basic auth. + ## 0.9.26 (2025-12-11) ### Changes diff --git a/python/mujinwebstackclient/controllerwebclientraw.py b/python/mujinwebstackclient/controllerwebclientraw.py index 6b404ef..0c720ba 100644 --- a/python/mujinwebstackclient/controllerwebclientraw.py +++ b/python/mujinwebstackclient/controllerwebclientraw.py @@ -291,6 +291,14 @@ def Request( response = self._session.request(method=method, url=url, timeout=timeout, headers=headers, **kwargs) + # if the response is 401 and JSON web token was used, it is possible that the token has expired + if response.status_code == 401 and isinstance(self._session.auth, JSONWebTokenAuth): + if self._session.auth._jsonWebToken is not None: + log.debug('request %s %s received unauthorized error, clearing cached json web token and retrying', method, url) + # clear the token and retry the request to fetch a new token via basic auth + self._session.auth._jsonWebToken = None + response = self._session.request(method=method, url=url, timeout=timeout, headers=headers, **kwargs) + # in verbose logging, log the caller if log.isEnabledFor(5): # logging.VERBOSE might not be available in the system log.verbose('request %s %s response %s took %.03f seconds:\n%s', method, url, response.status_code, response.elapsed.total_seconds(), '\n'.join([line.strip() for line in traceback.format_stack()[:-1]])) diff --git a/python/mujinwebstackclient/version.py b/python/mujinwebstackclient/version.py index d003960..b008342 100644 --- a/python/mujinwebstackclient/version.py +++ b/python/mujinwebstackclient/version.py @@ -1,3 +1,3 @@ -__version__ = '0.9.26' +__version__ = '0.9.27' # Do not forget to update CHANGELOG.md