Exemplo n.º 1
0
    def publish(self,
                name=None,
                data=None,
                client_id=None,
                connection_key=None,
                messages=None,
                timeout=None):
        """Publishes a message on this channel.

        :Parameters:
        - `name`: the name for this message.
        - `data`: the data for this message.
        - `connection_key`: connection key from a realtime connection, when publishing on behalf of it.
        - `messages`: list of `Message` objects to be published.
            Specify this param OR `name` and `data`.

        :attention: You can publish using `name` and `data` OR `messages`, never all three.
        """
        if not messages:
            messages = [Message(name, data, client_id, connection_key)]

        request_body_list = []
        for m in messages:
            if m.client_id == '*':
                raise IncompatibleClientIdException(
                    'Wildcard client_id is reserved and cannot be used when publishing messages',
                    400, 40012)
            elif m.client_id is not None and not self.ably.auth.can_assume_client_id(
                    m.client_id):
                raise IncompatibleClientIdException(
                    'Cannot publish with client_id \'{}\' as it is incompatible with the '
                    'current configured client_id \'{}\''.format(
                        m.client_id, self.ably.auth.client_id), 400, 40012)

            if self.cipher:
                m.encrypt(self.__cipher)

            request_body_list.append(m)

        if not self.ably.options.use_binary_protocol:
            if len(request_body_list) == 1:
                request_body = request_body_list[0].as_json()
            else:
                request_body = json.dumps(request_body_list,
                                          cls=MessageJSONEncoder)
        else:
            if len(request_body_list) == 1:
                request_body = request_body_list[0].as_msgpack()
            else:
                request_body = msgpack.packb([
                    message.as_dict(binary=True)
                    for message in request_body_list
                ],
                                             use_bin_type=True)

        path = '/channels/%s/publish' % self.__name

        return self.ably.http.post(path, body=request_body, timeout=timeout)
Exemplo n.º 2
0
    def __publish_request_body(self,
                               name=None,
                               data=None,
                               client_id=None,
                               extras=None,
                               messages=None):
        """
        Helper private method, separated from publish() to test RSL1j
        """
        if not messages:
            messages = [Message(name, data, client_id, extras=extras)]

        # Idempotent publishing
        if self.ably.options.idempotent_rest_publishing:
            # RSL1k1
            if all(message.id is None for message in messages):
                base_id = base64.b64encode(os.urandom(12)).decode()
                for serial, message in enumerate(messages):
                    message.id = u'{}:{}'.format(base_id, serial)

        request_body_list = []
        for m in messages:
            if m.client_id == '*':
                raise IncompatibleClientIdException(
                    'Wildcard client_id is reserved and cannot be used when publishing messages',
                    400, 40012)
            elif m.client_id is not None and not self.ably.auth.can_assume_client_id(
                    m.client_id):
                raise IncompatibleClientIdException(
                    'Cannot publish with client_id \'{}\' as it is incompatible with the '
                    'current configured client_id \'{}\''.format(
                        m.client_id, self.ably.auth.client_id), 400, 40012)

            if self.cipher:
                m.encrypt(self.__cipher)

            request_body_list.append(m)

        request_body = [
            message.as_dict(binary=self.ably.options.use_binary_protocol)
            for message in request_body_list
        ]

        if len(request_body) == 1:
            request_body = request_body[0]

        return request_body
Exemplo n.º 3
0
    def _configure_client_id(self, new_client_id):
        # If new client ID from Ably is a wildcard, but preconfigured clientId is set,
        # then keep the existing clientId
        if self.client_id != '*' and new_client_id == '*':
            self.__client_id_validated = True
            return

        # If client_id is defined and not a wildcard, prevent it changing, this is not supported
        if self.client_id is not None and self.client_id != '*' and new_client_id != self.client_id:
            raise IncompatibleClientIdException(
                "Client ID is immutable once configured for a client. "
                "Client ID cannot be changed to '{}'".format(new_client_id), 400, 40012)

        self.__client_id_validated = True
        self.__client_id = new_client_id