Development of an internal social media platform with personalised dashboards for students
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

pyamqp.py 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. """
  2. kombu.transport.pyamqp
  3. ======================
  4. pure python amqp transport.
  5. """
  6. from __future__ import absolute_import
  7. import amqp
  8. from kombu.five import items
  9. from kombu.utils.amq_manager import get_manager
  10. from kombu.utils.text import version_string_as_tuple
  11. from . import base
  12. DEFAULT_PORT = 5672
  13. DEFAULT_SSL_PORT = 5671
  14. class Message(base.Message):
  15. def __init__(self, channel, msg, **kwargs):
  16. props = msg.properties
  17. super(Message, self).__init__(
  18. channel,
  19. body=msg.body,
  20. delivery_tag=msg.delivery_tag,
  21. content_type=props.get('content_type'),
  22. content_encoding=props.get('content_encoding'),
  23. delivery_info=msg.delivery_info,
  24. properties=msg.properties,
  25. headers=props.get('application_headers') or {},
  26. **kwargs)
  27. class Channel(amqp.Channel, base.StdChannel):
  28. Message = Message
  29. def prepare_message(self, body, priority=None,
  30. content_type=None, content_encoding=None,
  31. headers=None, properties=None, _Message=amqp.Message):
  32. """Prepares message so that it can be sent using this transport."""
  33. return _Message(
  34. body,
  35. priority=priority,
  36. content_type=content_type,
  37. content_encoding=content_encoding,
  38. application_headers=headers,
  39. **properties or {}
  40. )
  41. def message_to_python(self, raw_message):
  42. """Convert encoded message body back to a Python value."""
  43. return self.Message(self, raw_message)
  44. class Connection(amqp.Connection):
  45. Channel = Channel
  46. class Transport(base.Transport):
  47. Connection = Connection
  48. default_port = DEFAULT_PORT
  49. default_ssl_port = DEFAULT_SSL_PORT
  50. # it's very annoying that pyamqp sometimes raises AttributeError
  51. # if the connection is lost, but nothing we can do about that here.
  52. connection_errors = amqp.Connection.connection_errors
  53. channel_errors = amqp.Connection.channel_errors
  54. recoverable_connection_errors = \
  55. amqp.Connection.recoverable_connection_errors
  56. recoverable_channel_errors = amqp.Connection.recoverable_channel_errors
  57. driver_name = 'py-amqp'
  58. driver_type = 'amqp'
  59. supports_heartbeats = True
  60. supports_ev = True
  61. def __init__(self, client,
  62. default_port=None, default_ssl_port=None, **kwargs):
  63. self.client = client
  64. self.default_port = default_port or self.default_port
  65. self.default_ssl_port = default_ssl_port or self.default_ssl_port
  66. def driver_version(self):
  67. return amqp.__version__
  68. def create_channel(self, connection):
  69. return connection.channel()
  70. def drain_events(self, connection, **kwargs):
  71. return connection.drain_events(**kwargs)
  72. def establish_connection(self):
  73. """Establish connection to the AMQP broker."""
  74. conninfo = self.client
  75. for name, default_value in items(self.default_connection_params):
  76. if not getattr(conninfo, name, None):
  77. setattr(conninfo, name, default_value)
  78. if conninfo.hostname == 'localhost':
  79. conninfo.hostname = '127.0.0.1'
  80. opts = dict({
  81. 'host': conninfo.host,
  82. 'userid': conninfo.userid,
  83. 'password': conninfo.password,
  84. 'login_method': conninfo.login_method,
  85. 'virtual_host': conninfo.virtual_host,
  86. 'insist': conninfo.insist,
  87. 'ssl': conninfo.ssl,
  88. 'connect_timeout': conninfo.connect_timeout,
  89. 'heartbeat': conninfo.heartbeat,
  90. }, **conninfo.transport_options or {})
  91. conn = self.Connection(**opts)
  92. conn.client = self.client
  93. return conn
  94. def verify_connection(self, connection):
  95. return connection.connected
  96. def close_connection(self, connection):
  97. """Close the AMQP broker connection."""
  98. connection.client = None
  99. connection.close()
  100. def get_heartbeat_interval(self, connection):
  101. return connection.heartbeat
  102. def register_with_event_loop(self, connection, loop):
  103. loop.add_reader(connection.sock, self.on_readable, connection, loop)
  104. def heartbeat_check(self, connection, rate=2):
  105. return connection.heartbeat_tick(rate=rate)
  106. def qos_semantics_matches_spec(self, connection):
  107. props = connection.server_properties
  108. if props.get('product') == 'RabbitMQ':
  109. return version_string_as_tuple(props['version']) < (3, 3)
  110. return True
  111. @property
  112. def default_connection_params(self):
  113. return {
  114. 'userid': 'guest',
  115. 'password': 'guest',
  116. 'port': (self.default_ssl_port if self.client.ssl
  117. else self.default_port),
  118. 'hostname': 'localhost',
  119. 'login_method': 'AMQPLAIN',
  120. }
  121. def get_manager(self, *args, **kwargs):
  122. return get_manager(self.client, *args, **kwargs)