

    @property
    def id(self):
        return self.__id

    def __setattr__(self, name, value):
        if name in ['__id', 'id']:
            raise ImmutableError(name)
        else:
            super(API, self).__setattr__(name, value)

    def disconnect(self):
        ''' terminates server connection/s '''

        proxy = context.manager[self.id].get('proxy')
        persistent_auth = context.manager[self.id].get('persistent_auth')

        # If persistent authentication is enabled then we need to
        # send a last request as a hint to the server to close the
        # session:
        if proxy:
            if persistent_auth:
                try:
                    proxy.request(
                        method='GET',
                        url='',
                        last=True
                    )
                except Exception:
                    pass
        else:
            raise DisconnectedError

        # Clear context
        context.manager.drop(self.id)

        # Close all the connections in the pool:
        proxy.close()

    def test(self, throw_exception=False):
        ''' test server connectivity '''

        proxy = context.manager[self.id].get('proxy')
        if proxy:
            try :
                proxy.request(
                    method='GET',
                    url=''
                )
            except Exception as e:
                if throw_exception: raise e
                return False
            return True
        raise DisconnectedError

    def set_filter(self, filter):  # @ReservedAssignment
        ''' enables user permission based filtering '''
        if filter != None:
            context.manager[self.id].add(
                             'filter',
                             filter,
                             typ=bool
            )

    def set_renew_session(self, renew_session):
        ''' automatically renew expired authentication session '''
        if renew_session != None:
            context.manager[self.id].add(
                'renew_session',
                 renew_session,
                 Mode.RW,
                 typ=bool
            )

    def __set_session_timeout(self, session_timeout):
        ''' set authentication session timeout '''
        if session_timeout != None:
            context.manager[self.id].add(
                             'session_timeout',
                             session_timeout,
                             typ=int
            )

    def __enter__(self):
        return self

    def __exit__(self, type, value, tb):  # @ReservedAssignment
        self.disconnect()
