'Publish message to the specified exchange.
Arguments:
body (Any): Message body.
routing_key (str): Message routing key.
delivery_mode (enum): See :attr:`delivery_mode`.
mandatory (bool): Currently not supported.
immediate (bool): Currently not supported.
priority (int): Message priority. A number between 0 and 9.
content_type (str): Content type. Default is auto-detect.
content_encoding (str): Content encoding. Default is auto-detect.
serializer (str): Serializer to use. Default is auto-detect.
compression (str): Compression method to use.  Default is none.
headers (Dict): Mapping of arbitrary headers to pass along
with the message body.
exchange (Exchange, str): Override the exchange.
Note that this exchange must have been declared.
declare (Sequence[EntityT]): Optional list of required entities
that must have been declared before publishing the message.
The entities will be declared using
:func:`~kombu.common.maybe_declare`.
retry (bool): Retry publishing, or declaring entities if the
connection is lost.
retry_policy (Dict): Retry configuration, this is the keywords
supported by :meth:`~kombu.Connection.ensure`.
expiration (float): A TTL in seconds can be specified per message.
Default is no expiration.
**properties (Any): Additional message properties, see AMQP spec.'

def publish(self, body, routing_key=None, delivery_mode=None, mandatory=False, immediate=False, priority=0, content_type=None, content_encoding=None, serializer=None, headers=None, compression=None, exchange=None, retry=False, retry_policy=None, declare=None, expiration=None, **properties):

    _publish = self._publish
    declare = ([] if (declare is None) else declare)
    headers = ({} if (headers is None) else headers)
    retry_policy = ({} if (retry_policy is None) else retry_policy)
    routing_key = (self.routing_key if (routing_key is None) else routing_key)
    compression = (self.compression if (compression is None) else compression)
    (exchange_name, properties[u'delivery_mode']) = self._delivery_details((exchange or self.exchange), delivery_mode)
    if (expiration is not None):
        properties[u'expiration'] = str(int((expiration * 1000)))
    (body, content_type, content_encoding) = self._prepare(body, serializer, content_type, content_encoding, compression, headers)
    if (self.auto_declare and self.exchange.name):
        if (self.exchange not in declare):
            declare.append(self.exchange)
    if retry:
        _publish = self.connection.ensure(self, _publish, **retry_policy)
    return _publish(body, priority, content_type, content_encoding, headers, properties, routing_key, mandatory, immediate, exchange_name, declare)
