def __init__(self, address='localhost', port=DEFAULT_PORT, user=None, password=None, http_handler=None, timeout=None):
     if isinstance(timeout, (int, long, float)):
         self._query_timeout = float(timeout)
     else:
         self._query_timeout = DEFAULT_TIMEOUT
     urlo = urlparse.urlparse(address)
     if urlo.scheme == '':
         base_url = 'http://' + address + ':' + str(port)
         self.url = base_url + '/transmission/rpc'
     else:
         if urlo.port:
             self.url = urlo.scheme + '://' + urlo.hostname + ':' + str(urlo.port) + urlo.path
         else:
             self.url = urlo.scheme + '://' + urlo.hostname + urlo.path
         LOGGER.info('Using custom URL "' + self.url + '".')
         if urlo.username and urlo.password:
             user = urlo.username
             password = urlo.password
         elif urlo.username or urlo.password:
             LOGGER.warning('Either user or password missing, not using authentication.')
     if http_handler is None:
         self.http_handler = DefaultHTTPHandler()
     else:
         if hasattr(http_handler, 'set_authentication') and hasattr(http_handler, 'request'):
             self.http_handler = http_handler
         else:
             raise ValueError('Invalid HTTP handler.')
     if user and password:
         self.http_handler.set_authentication(self.url, user, password)
     elif user or password:
         LOGGER.warning('Either user or password missing, not using authentication.')
     self._sequence = 0
     self.session = Session()
     self.session_id = 0
     self.server_version = None
     self.protocol_version = None
     self.get_session()
     self.torrent_get_arguments = get_arguments('torrent-get'
                                                , self.rpc_version)
class Client(object):
    """
    Client is the class handling the Transmission JSON-RPC client protocol.
    """

    def __init__(self, address='localhost', port=DEFAULT_PORT, user=None, password=None, http_handler=None, timeout=None):
        if isinstance(timeout, (int, long, float)):
            self._query_timeout = float(timeout)
        else:
            self._query_timeout = DEFAULT_TIMEOUT
        urlo = urlparse.urlparse(address)
        if urlo.scheme == '':
            base_url = 'http://' + address + ':' + str(port)
            self.url = base_url + '/transmission/rpc'
        else:
            if urlo.port:
                self.url = urlo.scheme + '://' + urlo.hostname + ':' + str(urlo.port) + urlo.path
            else:
                self.url = urlo.scheme + '://' + urlo.hostname + urlo.path
            LOGGER.info('Using custom URL "' + self.url + '".')
            if urlo.username and urlo.password:
                user = urlo.username
                password = urlo.password
            elif urlo.username or urlo.password:
                LOGGER.warning('Either user or password missing, not using authentication.')
        if http_handler is None:
            self.http_handler = DefaultHTTPHandler()
        else:
            if hasattr(http_handler, 'set_authentication') and hasattr(http_handler, 'request'):
                self.http_handler = http_handler
            else:
                raise ValueError('Invalid HTTP handler.')
        if user and password:
            self.http_handler.set_authentication(self.url, user, password)
        elif user or password:
            LOGGER.warning('Either user or password missing, not using authentication.')
        self._sequence = 0
        self.session = Session()
        self.session_id = 0
        self.server_version = None
        self.protocol_version = None
        self.get_session()
        self.torrent_get_arguments = get_arguments('torrent-get'
                                                   , self.rpc_version)

    def _get_timeout(self):
        """
        Get current timeout for HTTP queries.
        """
        return self._query_timeout

    def _set_timeout(self, value):
        """
        Set timeout for HTTP queries.
        """
        self._query_timeout = float(value)

    def _del_timeout(self):
        """
        Reset the HTTP query timeout to the default.
        """
        self._query_timeout = DEFAULT_TIMEOUT

    timeout = property(_get_timeout, _set_timeout, _del_timeout, doc="HTTP query timeout.")

    def _http_query(self, query, timeout=None):
        """
        Query Transmission through HTTP.
        """
        headers = {'x-transmission-session-id': str(self.session_id)}
        result = {}
        request_count = 0
        if timeout is None:
            timeout = self._query_timeout
        while True:
            LOGGER.debug(json.dumps({'url': self.url, 'headers': headers, 'query': query, 'timeout': timeout}, indent=2))
            try:
                result = self.http_handler.request(self.url, query, headers, timeout)
                break
            except HTTPHandlerError, error:
                if error.code == 409:
                    LOGGER.info('Server responded with 409, trying to set session-id.')
                    if request_count > 1:
                        raise TransmissionError('Session ID negotiation failed.', error)
                    if 'x-transmission-session-id' in error.headers:
                        self.session_id = error.headers['x-transmission-session-id']
                        headers = {'x-transmission-session-id': str(self.session_id)}
                    else:
                        debug_httperror(error)
                        raise TransmissionError('Unknown conflict.', error)
                else:
                    debug_httperror(error)
                    raise TransmissionError('Request failed.', error)
            request_count += 1
        return result