docs: def get_client_token(self, client_id=None, client_secret=None,
                           op_host=None, op_discovery_path=None, scope=None,
                           auto_update=True):
          """Function to get the client token which can be used for protection in
          all future communication. The access token received by this method is
          stored in the config file and used as the `protection_access_token`
          for all subsequent calls to oxd.
  
          Parameters:
              * **client_id (str, optional):** client id from OP or from previous `setup_client` call
              * **client_secret (str, optional):** client secret from the OP or from `setup_client` call
              * **op_host (str, optional):** OP Host URL, default is read from the site configuration file
              * **op_discovery_path (str, optional):** op discovery path provided by OP
              * **scope (list, optional):** scopes of access required, default values are obtained from the config file
              * **auto_update(bool, optional):** automatically get a new access_token when the current one expires. If this is set to False, then the application must call `get_client_token` when the token expires to update the client with a new access token.
  
          Returns:
              **dict:** The client token and the refresh token in the form.
  
              Example response ::
  
                  {
                      "access_token":"6F9619FF-8B86-D011-B42D-00CF4FC964FF",
                      "expires_in": 399,
                      "refresh_token": "fr459f",
                      "scope": "openid"
                  }
  
          """
          # override the values from config
          params = dict(client_id=client_id, client_secret=client_secret,
                        op_host=op_host)
  
          if op_discovery_path:
              params['op_discovery_path'] = op_discovery_path
          if scope and isinstance(scope, list):
              params['scope'] = scope
  
          # If client id and secret aren't passed, then just read from the config
          if not client_id:
              params["client_id"] = self.config.get("client", "client_id")
          if not client_secret:
              params["client_secret"] = self.config.get("client",
                                                        "client_secret")
          if not op_host:
              params["op_host"] = self.config.get("client", "op_host")
          logger.debug("Sending command `get_client_token` with params %s",
                       params)
  
          response = self.msgr.request("get_client_token", **params)
          logger.debug("Received response: %s", response)
  
          if response['status'] == 'error':
              raise OxdServerError(response['data'])
  
          self.config.set("client", "protection_access_token",
                          response["data"]["access_token"])
          self.msgr.access_token = response["data"]["access_token"]
  
          # Setup a new timer thread to refresh the access token.
          if auto_update:
              interval = int(response['data']['expires_in'])
              args = [client_id, client_secret, op_host, op_discovery_path,
                      scope, auto_update]
              logger.info("Setting up a threading.Timer to get_client_token in "
                          "%s seconds", interval)
              t = Timer(interval, self.get_client_token, args)
              t.start()
  
          return response['data']