class_docstr: ClearML API Session class. 
class_docstr_tok: ["ClearML","API","Session","class","."]
docstr: Internal implementation for making a raw API request.
  - Constructs the api endpoint name
  - Injects the worker id into the headers
  - Allows custom authorization using a requests auth object
  - Intercepts `Unauthorized` responses and automatically attempts to refresh the session token once in this
    case (only once). This is done since permissions are embedded in the token, and addresses a case where
    server-side permissions have changed but are not reflected in the current token. Refreshing the token will
    generate a token with the updated permissions.
docstr_tok: ["Internal","implementation","for","making","a","raw","API","request",".","-","Constructs","the","api","endpoint","name","-","Injects","the","worker","id","into","the","headers","-","Allows","custom","authorization","using","a","requests","auth","object","-","Intercepts","`","Unauthorized","`","responses","and","automatically","attempts","to","refresh","the","session","token","once","in","this","case","(","only","once",")",".","This","is","done","since","permissions","are","embedded","in","the","token",",","and","addresses","a","case","where","server-side","permissions","have","changed","but","are","not","reflected","in","the","current","token",".","Refreshing","the","token","will","generate","a","token","with","the","updated","permissions","."]
code: def _send_request(
      self,
      service,
      action,
      version=None,
      method=None,
      headers=None,
      auth=None,
      data=None,
      json=None,
      refresh_token_if_unauthorized=True,
      params=None,
  ):
      """Internal implementation for making a raw API request.
      - Constructs the api endpoint name
      - Injects the worker id into the headers
      - Allows custom authorization using a requests auth object
      - Intercepts `Unauthorized` responses and automatically attempts to refresh the session token once in this
        case (only once). This is done since permissions are embedded in the token, and addresses a case where
        server-side permissions have changed but are not reflected in the current token. Refreshing the token will
        generate a token with the updated permissions.
      """
      if self._offline_mode:
          return None
  
      if not method:
          method = Request.def_method
  
      res = None
      host = self.host
      headers = headers.copy() if headers else {}
      for h in self._WORKER_HEADER:
          headers[h] = self.worker
      for h in self._CLIENT_HEADER:
          headers[h] = self.client
  
      token_refreshed_on_error = False
      url = (
          "{host}/v{version}/{service}.{action}"
          if version
          else "{host}/{service}.{action}"
      ).format(**locals())
      retry_counter = 0
      while True:
          if data and len(data) > self._write_session_data_size:
              timeout = self._write_session_timeout
          elif self._session_requests < 1:
              timeout = self._session_initial_timeout
          else:
              timeout = self._session_timeout
          try:
              if self._verbose and self._logger:
                  size = len(data or "")
                  if json and self._logger.level == logging.DEBUG:
                      size += len(json_lib.dumps(json))
                  self._logger.debug(
                      "%s: %s [%d bytes, %d headers]",
                      method.upper(),
                      url,
                      size,
                      len(headers or {}),
                  )
              res = self.__http_session.request(
                  method,
                  url,
                  headers=headers,
                  auth=auth,
                  data=data,
                  json=json,
                  timeout=timeout,
                  params=params,
              )
              if self._verbose and self._logger:
                  self._logger.debug("--> took %s", res.elapsed)
          # except Exception as ex:
          except SSLError as ex:
              retry_counter += 1
              # we should retry
              if retry_counter >= self._ssl_error_count_verbosity:
                  (self._logger or get_logger()).warning(
                      "SSLError Retrying {}".format(ex)
                  )
              sleep(0.1)
              continue
          except (
              ChunkedEncodingError,
              ContentDecodingError,
              StreamConsumedError,
          ) as ex:
              retry_counter += 1
              # we should retry
              if retry_counter >= self._ssl_error_count_verbosity:
                  (self._logger or get_logger()).warning(
                      "Network decoding error Retrying {}".format(ex)
                  )
              sleep(0.1)
              continue
  
          if (
              refresh_token_if_unauthorized
              and res.status_code == requests.codes.unauthorized
              and not token_refreshed_on_error
          ):
              # it seems we're unauthorized, so we'll try to refresh our token once in case permissions changed since
              # the last time we got the token, and try again
              self.refresh_token()
              token_refreshed_on_error = True
              # try again
              retry_counter += 1
              continue
          if (
              res.status_code == requests.codes.service_unavailable
              and self.config.get(
                  "api.http.wait_on_maintenance_forever", True
              )
          ):
              (self._logger or get_logger()).warning(
                  "Service unavailable: {} is undergoing maintenance, retrying...".format(
                      host
                  )
              )
              retry_counter += 1
              continue
          break
      self._session_requests += 1
      return res
  
imports: from __future__ import print_function
  import json
  import logging
  import os
  import sys
  import types
  import weakref
  from socket import gethostname
  from time import sleep
  import jwt
  import requests
  import six
  from requests.auth import HTTPBasicAuth
  from requests.exceptions import ChunkedEncodingError, ContentDecodingError, StreamConsumedError
  from six.moves.urllib.parse import urlparse, urlunparse
  from typing import List, Optional
  from .callresult import CallResult
  from .defs import ENV_VERBOSE, ENV_HOST, ENV_ACCESS_KEY, ENV_SECRET_KEY, ENV_WEB_HOST, ENV_FILES_HOST, ENV_OFFLINE_MODE, ENV_AUTH_TOKEN, ENV_DISABLE_VAULT_SUPPORT, ENV_ENABLE_ENV_CONFIG_SECTION, ENV_ENABLE_FILES_CONFIG_SECTION, ENV_API_EXTRA_RETRY_CODES, ENV_API_DEFAULT_REQ_METHOD, ENV_FORCE_MAX_API_VERSION, ENV_IGNORE_MISSING_CONFIG, MissingConfigError
  from .request import Request, BatchRequest
  from .token_manager import TokenManager
  from ..utils import get_http_session_with_retry, urllib_log_warning_setup
  from ...backend_config import ConfigurationError
  from ...backend_config.defs import get_config_file
  from ...debugging import get_logger
  from ...debugging.log import resolve_logging_level
  from ...utilities.pyhocon import ConfigTree, ConfigFactory
  from ...version import __version__
  from ...backend_config.utils import apply_files, apply_environment
label_desc: Use image node_id 14 for calling the Session obj's underlying member method code with example usage: obj._send_request(service, action, version, method, headers, auth, data, json, refresh_token_if_unauthorized, params) and returns: res, None