def __init__(self, device_id, resource_path, **extra_filters): """Triggers on response to a request for a current resource value .. warning:: This functionality is considered experimental; the interface may change in future releases :param device_id: a device identifier :param resource_path: a resource path :param extra_filters: """ super(CurrentResourceValue, self).__init__() self.device_id = device_id self.resource_path = resource_path # each request is unique self.async_id = utils.new_async_id() LOG.debug('new async id: %s', self.async_id) self._route_keys = expand_dict_as_keys( dict( id=self.async_id, channel=ChannelIdentifiers.async_responses, )) self._optional_filters = {} self._optional_filters.update(extra_filters) self._optional_filter_keys = expand_dict_as_keys( self._optional_filters)
def __init__(self, device_id=None, **extra_filters): """Channel""" self._route_keys = expand_dict_as_keys( dict(channel=[ _API_CHANNELS.de_registrations, _API_CHANNELS.reg_updates, _API_CHANNELS.registrations_expired, _API_CHANNELS.registrations, ], )) self._optional_filters = {} if device_id is not None: self._optional_filters['device_id'] = device_id self._optional_filters.update(extra_filters) self._optional_filter_keys = expand_dict_as_keys( self._optional_filters)
def test_product(self): self.assertEqual(expand_dict_as_keys(dict(a=1, b=[2, 3], c=[4, 5])), [ tuple([('a', 1), ('b', 2), ('c', 4)]), tuple([('a', 1), ('b', 2), ('c', 5)]), tuple([('a', 1), ('b', 3), ('c', 4)]), tuple([('a', 1), ('b', 3), ('c', 5)]), ])
def __init__(self, device_id, resource_path, **extra_filters): """Channel""" raise NotImplementedError('coming soon™') self.device_id = device_id self.resource_path = resource_path self._route_keys = expand_dict_as_keys( dict( device_id=device_id, resource_path=resource_path, channel=_API_CHANNELS.notifications, )) self._optional_filters = {} self._optional_filters.update(extra_filters) self._optional_filter_keys = expand_dict_as_keys( self._optional_filters)
def __init__(self, device_id, resource_path, **extra_filters): """Channel""" self.device_id = device_id self.resource_path = resource_path # each request is unique self.async_id = utils.new_async_id() logging.debug('new async id: %s', self.async_id) self._route_keys = expand_dict_as_keys( dict( id=self.async_id, channel=_API_CHANNELS.async_responses, )) self._optional_filters = {} self._optional_filters.update(extra_filters) self._optional_filter_keys = expand_dict_as_keys( self._optional_filters)
def __init__(self, device_id=None, **extra_filters): """Triggers on changes to registration state of devices .. warning:: This functionality is considered experimental; the interface may change in future releases :param device_id: a device identifier :param extra_filters: additional filters e.g. dict(channel=API_CHANNELS.registrations) """ super(DeviceStateChanges, self).__init__() self._route_keys = expand_dict_as_keys( dict(channel=[ ChannelIdentifiers.de_registrations, ChannelIdentifiers.reg_updates, ChannelIdentifiers.registrations_expired, ChannelIdentifiers.registrations, ], )) self._optional_filters = {} if device_id is not None: self._optional_filters['device_id'] = device_id self._optional_filters.update(extra_filters)
def test_empty(self): self.assertEqual(expand_dict_as_keys(dict()), [ tuple() ])
def test_usage(self): keys = set(expand_dict_as_keys(dict(a=1, b=[2, 3], c=[4, 5]))) self.assertIn(expand_dict_as_keys(dict(a=1, b=2, c=5))[0], keys) self.assertNotIn(expand_dict_as_keys(dict(a=1, b=2, c=6))[0], keys)
def test_expand(self): self.assertEqual(expand_dict_as_keys(dict(a=1, b=[2, 3])), [ tuple([('a', 1), ('b', 2)]), tuple([('a', 1), ('b', 3)]), ])
def test_static_sorted(self): self.assertEqual(expand_dict_as_keys(dict(c=1, b=2)), [ tuple([('b', 2), ('c', 1)]) ])
def test_static(self): self.assertEqual(expand_dict_as_keys(dict(a=1, b=2)), [ tuple([('a', 1), ('b', 2)]) ])
def __init__(self, device_id=None, resource_path=None, first_value=FirstValue.on_value_update, **extra_filters): """Triggers when a resource's value changes .. warning:: This functionality is considered experimental; the interface may change in future releases :param device_id: device identifier, (or list thereof), optionally ending with wildcard * :param resource_path: resource path, (or list thereof), optionally ending with wildcard * :param first_value: mode for adjusting immediacy of subscribed values :param extra_filters: other local key-value filters """ super(ResourceValues, self).__init__() self.device_ids = [ str(d) for d in utils.ensure_listable(device_id) if d ] self.resource_paths = [ str(p) for p in utils.ensure_listable(resource_path) if p ] # TODO(endpoint_type) support needs the endpoint_type or identifier in presub api response # self.endpoint_type self._immediacy = first_value self._presubscription_registry = None # type: PreSubscriptionRegistry # for filtering inbound notifications (with wildcards) self._local_filters = {} # for configuring the router (which has no wildcard behaviour) self._route_seeds = { 'channel': ChannelIdentifiers.notifications, } # turn our parameters into a presubscriptions-compatible list (one device id per entry) # note: pluralised 'resource_paths' self._sdk_presub_params = [{ k: v for k, v in dict(device_id=d, resource_paths=self.resource_paths).items() if v } for d in self.device_ids or [None]] # api sends back different field names on the notification channel so remap them before # putting them in the routing table for api_key_name, values in dict(ep=self.device_ids, path=self.resource_paths).items(): has_wildcards = any(self._is_wildcard(v) for v in values if v) for to_validate in values: if to_validate is None: continue if not self._validate_wildcard(to_validate): raise ValueError( 'Wildcards can only be used at the end of values: "%s"' % (to_validate, )) # local filters recreate behaviour of server-side wildcard filter, but are not # routable (can't look them up in a dictionary) # routable filters are for explicit key-value pairs if has_wildcards: self._local_filters.setdefault(api_key_name, []).append(to_validate) else: self._route_seeds.setdefault(api_key_name, []).append(to_validate) self._route_keys = expand_dict_as_keys(self._route_seeds) self._optional_filters = {} self._optional_filters.update(extra_filters) self._optional_filter_keys = expand_dict_as_keys( self._optional_filters) self.add_filter_function(self._wildcard_filter)