Codebase list python-amqp / 44d62e8
Import upstream version 5.0.6+git20210401.1.7300741 Debian Janitor 2 years ago
12 changed file(s) with 686 addition(s) and 113 deletion(s). Raw diff Collapse all Expand all
33 py-amqp is fork of amqplib used by Kombu containing additional features and improvements.
44 The previous amqplib changelog is here:
55 http://code.google.com/p/py-amqplib/source/browse/CHANGES
6
7 .. _version-5.0.6:
8
9 5.0.6
10 =====
11 :release-date: 2021-04-01 10:45 A.M. UTC+6:00
12 :release-by: Asif Saif Uddin
13
14 - Change the order in which context.check_hostname and context.verify_mode get set
15 in SSLTransport._wrap_socket_sni. Fixes bug introduced in 5.0.3 where setting
16 context.verify_mode = ssl.CERT_NONE would raise
17 "ValueError: Cannot set verify_mode to CERT_NONE when check_hostname is enabled."
18 Setting context.check_hostname prior to setting context.verify_mode resolves the
19 issue.
20 - Remove TCP_USER_TIMEOUT option for Solaris (#355)
21 - Pass long_description to setup() (#353)
22 - Fix for tox-docker 2.0
23 - Moved to GitHub actions CI (#359)
24
25 .. _version-5.0.5:
26
27 5.0.5
28 =====
29 :release-date: 2021-01-28 4:30 P.M UTC+6:00
30 :release-by: Asif Saif Uddin
31
32 - Removed mistakenly introduced code which was causing import errors
33
34
35
36 .. _version-5.0.4:
37
38 5.0.4
39 =====
40 :release-date: 2021-01-28 2:30 P.M UTC+6:00
41 :release-by: Asif Saif Uddin
42
43 - Add missing load_default_certs() call to fix a regression in v5.0.3 release. (#350)
44
645
746 .. _version-5.0.3:
847
0 Metadata-Version: 1.2
0 Metadata-Version: 2.1
11 Name: amqp
2 Version: 5.0.3
2 Version: 5.0.6
33 Summary: Low-level AMQP client for Python (fork of amqplib).
44 Home-page: http://github.com/celery/py-amqp
55 Author: Barry Pederson
66 Author-email: pyamqp@celeryproject.org
77 Maintainer: Asif Saif Uddin, Matus Valo
88 License: BSD
9 Description: UNKNOWN
9 Description: =====================================================================
10 Python AMQP 0.9.1 client library
11 =====================================================================
12
13 |build-status| |coverage| |license| |wheel| |pyversion| |pyimp|
14
15 :Version: 5.0.6
16 :Web: https://amqp.readthedocs.io/
17 :Download: https://pypi.org/project/amqp/
18 :Source: http://github.com/celery/py-amqp/
19 :Keywords: amqp, rabbitmq
20
21 About
22 =====
23
24 This is a fork of amqplib_ which was originally written by Barry Pederson.
25 It is maintained by the Celery_ project, and used by `kombu`_ as a pure python
26 alternative when `librabbitmq`_ is not available.
27
28 This library should be API compatible with `librabbitmq`_.
29
30 .. _amqplib: https://pypi.org/project/amqplib/
31 .. _Celery: http://celeryproject.org/
32 .. _kombu: https://kombu.readthedocs.io/
33 .. _librabbitmq: https://pypi.org/project/librabbitmq/
34
35 Differences from `amqplib`_
36 ===========================
37
38 - Supports draining events from multiple channels (``Connection.drain_events``)
39 - Support for timeouts
40 - Channels are restored after channel error, instead of having to close the
41 connection.
42 - Support for heartbeats
43
44 - ``Connection.heartbeat_tick(rate=2)`` must called at regular intervals
45 (half of the heartbeat value if rate is 2).
46 - Or some other scheme by using ``Connection.send_heartbeat``.
47 - Supports RabbitMQ extensions:
48 - Consumer Cancel Notifications
49 - by default a cancel results in ``ChannelError`` being raised
50 - but not if a ``on_cancel`` callback is passed to ``basic_consume``.
51 - Publisher confirms
52 - ``Channel.confirm_select()`` enables publisher confirms.
53 - ``Channel.events['basic_ack'].append(my_callback)`` adds a callback
54 to be called when a message is confirmed. This callback is then
55 called with the signature ``(delivery_tag, multiple)``.
56 - Exchange-to-exchange bindings: ``exchange_bind`` / ``exchange_unbind``.
57 - ``Channel.confirm_select()`` enables publisher confirms.
58 - ``Channel.events['basic_ack'].append(my_callback)`` adds a callback
59 to be called when a message is confirmed. This callback is then
60 called with the signature ``(delivery_tag, multiple)``.
61 - Authentication Failure Notifications
62 Instead of just closing the connection abruptly on invalid
63 credentials, py-amqp will raise an ``AccessRefused`` error
64 when connected to rabbitmq-server 3.2.0 or greater.
65 - Support for ``basic_return``
66 - Uses AMQP 0-9-1 instead of 0-8.
67 - ``Channel.access_request`` and ``ticket`` arguments to methods
68 **removed**.
69 - Supports the ``arguments`` argument to ``basic_consume``.
70 - ``internal`` argument to ``exchange_declare`` removed.
71 - ``auto_delete`` argument to ``exchange_declare`` deprecated
72 - ``insist`` argument to ``Connection`` removed.
73 - ``Channel.alerts`` has been removed.
74 - Support for ``Channel.basic_recover_async``.
75 - ``Channel.basic_recover`` deprecated.
76 - Exceptions renamed to have idiomatic names:
77 - ``AMQPException`` -> ``AMQPError``
78 - ``AMQPConnectionException`` -> ConnectionError``
79 - ``AMQPChannelException`` -> ChannelError``
80 - ``Connection.known_hosts`` removed.
81 - ``Connection`` no longer supports redirects.
82 - ``exchange`` argument to ``queue_bind`` can now be empty
83 to use the "default exchange".
84 - Adds ``Connection.is_alive`` that tries to detect
85 whether the connection can still be used.
86 - Adds ``Connection.connection_errors`` and ``.channel_errors``,
87 a list of recoverable errors.
88 - Exposes the underlying socket as ``Connection.sock``.
89 - Adds ``Channel.no_ack_consumers`` to keep track of consumer tags
90 that set the no_ack flag.
91 - Slightly better at error recovery
92
93 Quick overview
94 ==============
95
96 Simple producer publishing messages to ``test`` queue using default exchange:
97
98 .. code:: python
99
100 import amqp
101
102 with amqp.Connection('broker.example.com') as c:
103 ch = c.channel()
104 ch.basic_publish(amqp.Message('Hello World'), routing_key='test')
105
106 Producer publishing to ``test_exchange`` exchange with publisher confirms enabled and using virtual_host ``test_vhost``:
107
108 .. code:: python
109
110 import amqp
111
112 with amqp.Connection(
113 'broker.example.com', exchange='test_exchange',
114 confirm_publish=True, virtual_host='test_vhost'
115 ) as c:
116 ch = c.channel()
117 ch.basic_publish(amqp.Message('Hello World'), routing_key='test')
118
119 Consumer with acknowledgments enabled:
120
121 .. code:: python
122
123 import amqp
124
125 with amqp.Connection('broker.example.com') as c:
126 ch = c.channel()
127 def on_message(message):
128 print('Received message (delivery tag: {}): {}'.format(message.delivery_tag, message.body))
129 ch.basic_ack(message.delivery_tag)
130 ch.basic_consume(queue='test', callback=on_message)
131 while True:
132 c.drain_events()
133
134
135 Consumer with acknowledgments disabled:
136
137 .. code:: python
138
139 import amqp
140
141 with amqp.Connection('broker.example.com') as c:
142 ch = c.channel()
143 def on_message(message):
144 print('Received message (delivery tag: {}): {}'.format(message.delivery_tag, message.body))
145 ch.basic_consume(queue='test', callback=on_message, no_ack=True)
146 while True:
147 c.drain_events()
148
149 Speedups
150 ========
151
152 This library has **experimental** support of speedups. Speedups are implemented using Cython. To enable speedups, ``CELERY_ENABLE_SPEEDUPS`` environment variable must be set during building/installation.
153 Currently speedups can be installed:
154
155 1. using source package (using ``--no-binary`` switch):
156
157 .. code:: shell
158
159 CELERY_ENABLE_SPEEDUPS=true pip install --no-binary :all: amqp
160
161
162 2. building directly source code:
163
164 .. code:: shell
165
166 CELERY_ENABLE_SPEEDUPS=true python setup.py install
167
168 Further
169 =======
170
171 - Differences between AMQP 0.8 and 0.9.1
172
173 http://www.rabbitmq.com/amqp-0-8-to-0-9-1.html
174
175 - AMQP 0.9.1 Quick Reference
176
177 http://www.rabbitmq.com/amqp-0-9-1-quickref.html
178
179 - RabbitMQ Extensions
180
181 http://www.rabbitmq.com/extensions.html
182
183 - For more information about AMQP, visit
184
185 http://www.amqp.org
186
187 - For other Python client libraries see:
188
189 http://www.rabbitmq.com/devtools.html#python-dev
190
191 .. |build-status| image:: https://api.travis-ci.com/celery/py-amqp.png?branch=master
192 :alt: Build status
193 :target: https://travis-ci.com/celery/py-amqp
194
195 .. |coverage| image:: https://codecov.io/github/celery/py-amqp/coverage.svg?branch=master
196 :target: https://codecov.io/github/celery/py-amqp?branch=master
197
198 .. |license| image:: https://img.shields.io/pypi/l/amqp.svg
199 :alt: BSD License
200 :target: https://opensource.org/licenses/BSD-3-Clause
201
202 .. |wheel| image:: https://img.shields.io/pypi/wheel/amqp.svg
203 :alt: Python AMQP can be installed via wheel
204 :target: https://pypi.org/project/amqp/
205
206 .. |pyversion| image:: https://img.shields.io/pypi/pyversions/amqp.svg
207 :alt: Supported Python versions.
208 :target: https://pypi.org/project/amqp/
209
210 .. |pyimp| image:: https://img.shields.io/pypi/implementation/amqp.svg
211 :alt: Support Python implementations.
212 :target: https://pypi.org/project/amqp/
213
214 py-amqp as part of the Tidelift Subscription
215 ============================================
216
217 The maintainers of py-amqp and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/subscription/pkg/pypi-amqp?utm_source=pypi-amqp&utm_medium=referral&utm_campaign=readme&utm_term=repo)
218
219
10220 Keywords: amqp rabbitmq cloudamqp messaging
11221 Platform: any
12222 Classifier: Development Status :: 5 - Production/Stable
22232 Classifier: Intended Audience :: Developers
23233 Classifier: Operating System :: OS Independent
24234 Requires-Python: >=3.6
235 Description-Content-Type: text/x-rst
33
44 |build-status| |coverage| |license| |wheel| |pyversion| |pyimp|
55
6 :Version: 5.0.3
6 :Version: 5.0.6
77 :Web: https://amqp.readthedocs.io/
88 :Download: https://pypi.org/project/amqp/
99 :Source: http://github.com/celery/py-amqp/
145145
146146 1. using source package (using ``--no-binary`` switch):
147147
148 .. code-block::
149 CELERY_ENABLE_SPEEDUPS=true pip install --no-binary :all: amqp
148 .. code:: shell
149
150 CELERY_ENABLE_SPEEDUPS=true pip install --no-binary :all: amqp
150151
151152
152153 2. building directly source code:
153154
154 .. code-block::
155 CELERY_ENABLE_SPEEDUPS=true python setup.py install
155 .. code:: shell
156
157 CELERY_ENABLE_SPEEDUPS=true python setup.py install
156158
157159 Further
158160 =======
201203 :target: https://pypi.org/project/amqp/
202204
203205 py-amqp as part of the Tidelift Subscription
204 =======
206 ============================================
205207
206208 The maintainers of py-amqp and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/subscription/pkg/pypi-amqp?utm_source=pypi-amqp&utm_medium=referral&utm_campaign=readme&utm_term=repo)
207209
33 import re
44 from collections import namedtuple
55
6 __version__ = '5.0.3'
6 __version__ = '5.0.6'
77 __author__ = 'Barry Pederson'
88 __maintainer__ = 'Asif Saif Uddin, Matus Valo'
99 __contact__ = 'pyamqp@celeryproject.org'
297297
298298 This method asks the peer to pause or restart the flow of
299299 content data. This is a simple flow-control mechanism that a
300 peer can use to avoid oveflowing its queues or otherwise
300 peer can use to avoid overflowing its queues or otherwise
301301 finding itself receiving more messages than it can process.
302302 Note that this method is not intended for window control. The
303303 peer that receives a request to stop sending content should
321321
322322 A peer MAY use the Channel.Flow method to throttle
323323 incoming content data for internal reasons, for example,
324 when exchangeing data over a slower connection.
324 when exchanging data over a slower connection.
325325
326326 RULE:
327327
346346
347347 This method asks the peer to pause or restart the flow of
348348 content data. This is a simple flow-control mechanism that a
349 peer can use to avoid oveflowing its queues or otherwise
349 peer can use to avoid overflowing its queues or otherwise
350350 finding itself receiving more messages than it can process.
351351 Note that this method is not intended for window control. The
352352 peer that receives a request to stop sending content should
370370
371371 A peer MAY use the Channel.Flow method to throttle
372372 incoming content data for internal reasons, for example,
373 when exchangeing data over a slower connection.
373 when exchanging data over a slower connection.
374374
375375 RULE:
376376
13971397 This method cancels a consumer. This does not affect already
13981398 delivered messages, but it does mean the server will not send
13991399 any more messages for that consumer. The client may receive
1400 an abitrary number of messages in between sending the cancel
1400 an arbitrary number of messages in between sending the cancel
14011401 method and receiving the cancel-ok reply.
14021402
14031403 RULE:
6161
6262 # illumos does not allow to set the TCP_MAXSEG socket option,
6363 # even if the Oracle documentation says otherwise.
64 # TCP_USER_TIMEOUT does not exist on Solaris 11.4
6465 elif sys.platform.startswith('sunos'):
6566 KNOWN_TCP_OPTS.remove('TCP_MAXSEG')
67 KNOWN_TCP_OPTS.remove('TCP_USER_TIMEOUT')
6668
6769 # aix does not allow to set the TCP_MAXSEG
6870 # or the TCP_USER_TIMEOUT socket options.
524524 context.load_verify_locations(ca_certs)
525525 if ciphers is not None:
526526 context.set_ciphers(ciphers)
527 if cert_reqs is not None:
528 context.verify_mode = cert_reqs
529 # Set SNI headers if supported
527 # Set SNI headers if supported.
528 # Must set context.check_hostname before setting context.verify_mode
529 # to avoid setting context.verify_mode=ssl.CERT_NONE while
530 # context.check_hostname is still True (the default value in context
531 # if client-side) which results in the following exception:
532 # ValueError: Cannot set verify_mode to CERT_NONE when check_hostname
533 # is enabled.
530534 try:
531535 context.check_hostname = (
532536 ssl.HAS_SNI and server_hostname is not None
533537 )
534538 except AttributeError:
535539 pass # ask forgiveness not permission
540
541 # See note above re: ordering for context.check_hostname and
542 # context.verify_mode assignments.
543 if cert_reqs is not None:
544 context.verify_mode = cert_reqs
545
546 if ca_certs is None and context.verify_mode != ssl.CERT_NONE:
547 purpose = (
548 ssl.Purpose.CLIENT_AUTH
549 if server_side
550 else ssl.Purpose.SERVER_AUTH
551 )
552 context.load_default_certs(purpose)
536553
537554 sock = context.wrap_socket(**opts)
538555 return sock
0 Metadata-Version: 1.2
0 Metadata-Version: 2.1
11 Name: amqp
2 Version: 5.0.3
2 Version: 5.0.6
33 Summary: Low-level AMQP client for Python (fork of amqplib).
44 Home-page: http://github.com/celery/py-amqp
55 Author: Barry Pederson
66 Author-email: pyamqp@celeryproject.org
77 Maintainer: Asif Saif Uddin, Matus Valo
88 License: BSD
9 Description: UNKNOWN
9 Description: =====================================================================
10 Python AMQP 0.9.1 client library
11 =====================================================================
12
13 |build-status| |coverage| |license| |wheel| |pyversion| |pyimp|
14
15 :Version: 5.0.6
16 :Web: https://amqp.readthedocs.io/
17 :Download: https://pypi.org/project/amqp/
18 :Source: http://github.com/celery/py-amqp/
19 :Keywords: amqp, rabbitmq
20
21 About
22 =====
23
24 This is a fork of amqplib_ which was originally written by Barry Pederson.
25 It is maintained by the Celery_ project, and used by `kombu`_ as a pure python
26 alternative when `librabbitmq`_ is not available.
27
28 This library should be API compatible with `librabbitmq`_.
29
30 .. _amqplib: https://pypi.org/project/amqplib/
31 .. _Celery: http://celeryproject.org/
32 .. _kombu: https://kombu.readthedocs.io/
33 .. _librabbitmq: https://pypi.org/project/librabbitmq/
34
35 Differences from `amqplib`_
36 ===========================
37
38 - Supports draining events from multiple channels (``Connection.drain_events``)
39 - Support for timeouts
40 - Channels are restored after channel error, instead of having to close the
41 connection.
42 - Support for heartbeats
43
44 - ``Connection.heartbeat_tick(rate=2)`` must called at regular intervals
45 (half of the heartbeat value if rate is 2).
46 - Or some other scheme by using ``Connection.send_heartbeat``.
47 - Supports RabbitMQ extensions:
48 - Consumer Cancel Notifications
49 - by default a cancel results in ``ChannelError`` being raised
50 - but not if a ``on_cancel`` callback is passed to ``basic_consume``.
51 - Publisher confirms
52 - ``Channel.confirm_select()`` enables publisher confirms.
53 - ``Channel.events['basic_ack'].append(my_callback)`` adds a callback
54 to be called when a message is confirmed. This callback is then
55 called with the signature ``(delivery_tag, multiple)``.
56 - Exchange-to-exchange bindings: ``exchange_bind`` / ``exchange_unbind``.
57 - ``Channel.confirm_select()`` enables publisher confirms.
58 - ``Channel.events['basic_ack'].append(my_callback)`` adds a callback
59 to be called when a message is confirmed. This callback is then
60 called with the signature ``(delivery_tag, multiple)``.
61 - Authentication Failure Notifications
62 Instead of just closing the connection abruptly on invalid
63 credentials, py-amqp will raise an ``AccessRefused`` error
64 when connected to rabbitmq-server 3.2.0 or greater.
65 - Support for ``basic_return``
66 - Uses AMQP 0-9-1 instead of 0-8.
67 - ``Channel.access_request`` and ``ticket`` arguments to methods
68 **removed**.
69 - Supports the ``arguments`` argument to ``basic_consume``.
70 - ``internal`` argument to ``exchange_declare`` removed.
71 - ``auto_delete`` argument to ``exchange_declare`` deprecated
72 - ``insist`` argument to ``Connection`` removed.
73 - ``Channel.alerts`` has been removed.
74 - Support for ``Channel.basic_recover_async``.
75 - ``Channel.basic_recover`` deprecated.
76 - Exceptions renamed to have idiomatic names:
77 - ``AMQPException`` -> ``AMQPError``
78 - ``AMQPConnectionException`` -> ConnectionError``
79 - ``AMQPChannelException`` -> ChannelError``
80 - ``Connection.known_hosts`` removed.
81 - ``Connection`` no longer supports redirects.
82 - ``exchange`` argument to ``queue_bind`` can now be empty
83 to use the "default exchange".
84 - Adds ``Connection.is_alive`` that tries to detect
85 whether the connection can still be used.
86 - Adds ``Connection.connection_errors`` and ``.channel_errors``,
87 a list of recoverable errors.
88 - Exposes the underlying socket as ``Connection.sock``.
89 - Adds ``Channel.no_ack_consumers`` to keep track of consumer tags
90 that set the no_ack flag.
91 - Slightly better at error recovery
92
93 Quick overview
94 ==============
95
96 Simple producer publishing messages to ``test`` queue using default exchange:
97
98 .. code:: python
99
100 import amqp
101
102 with amqp.Connection('broker.example.com') as c:
103 ch = c.channel()
104 ch.basic_publish(amqp.Message('Hello World'), routing_key='test')
105
106 Producer publishing to ``test_exchange`` exchange with publisher confirms enabled and using virtual_host ``test_vhost``:
107
108 .. code:: python
109
110 import amqp
111
112 with amqp.Connection(
113 'broker.example.com', exchange='test_exchange',
114 confirm_publish=True, virtual_host='test_vhost'
115 ) as c:
116 ch = c.channel()
117 ch.basic_publish(amqp.Message('Hello World'), routing_key='test')
118
119 Consumer with acknowledgments enabled:
120
121 .. code:: python
122
123 import amqp
124
125 with amqp.Connection('broker.example.com') as c:
126 ch = c.channel()
127 def on_message(message):
128 print('Received message (delivery tag: {}): {}'.format(message.delivery_tag, message.body))
129 ch.basic_ack(message.delivery_tag)
130 ch.basic_consume(queue='test', callback=on_message)
131 while True:
132 c.drain_events()
133
134
135 Consumer with acknowledgments disabled:
136
137 .. code:: python
138
139 import amqp
140
141 with amqp.Connection('broker.example.com') as c:
142 ch = c.channel()
143 def on_message(message):
144 print('Received message (delivery tag: {}): {}'.format(message.delivery_tag, message.body))
145 ch.basic_consume(queue='test', callback=on_message, no_ack=True)
146 while True:
147 c.drain_events()
148
149 Speedups
150 ========
151
152 This library has **experimental** support of speedups. Speedups are implemented using Cython. To enable speedups, ``CELERY_ENABLE_SPEEDUPS`` environment variable must be set during building/installation.
153 Currently speedups can be installed:
154
155 1. using source package (using ``--no-binary`` switch):
156
157 .. code:: shell
158
159 CELERY_ENABLE_SPEEDUPS=true pip install --no-binary :all: amqp
160
161
162 2. building directly source code:
163
164 .. code:: shell
165
166 CELERY_ENABLE_SPEEDUPS=true python setup.py install
167
168 Further
169 =======
170
171 - Differences between AMQP 0.8 and 0.9.1
172
173 http://www.rabbitmq.com/amqp-0-8-to-0-9-1.html
174
175 - AMQP 0.9.1 Quick Reference
176
177 http://www.rabbitmq.com/amqp-0-9-1-quickref.html
178
179 - RabbitMQ Extensions
180
181 http://www.rabbitmq.com/extensions.html
182
183 - For more information about AMQP, visit
184
185 http://www.amqp.org
186
187 - For other Python client libraries see:
188
189 http://www.rabbitmq.com/devtools.html#python-dev
190
191 .. |build-status| image:: https://api.travis-ci.com/celery/py-amqp.png?branch=master
192 :alt: Build status
193 :target: https://travis-ci.com/celery/py-amqp
194
195 .. |coverage| image:: https://codecov.io/github/celery/py-amqp/coverage.svg?branch=master
196 :target: https://codecov.io/github/celery/py-amqp?branch=master
197
198 .. |license| image:: https://img.shields.io/pypi/l/amqp.svg
199 :alt: BSD License
200 :target: https://opensource.org/licenses/BSD-3-Clause
201
202 .. |wheel| image:: https://img.shields.io/pypi/wheel/amqp.svg
203 :alt: Python AMQP can be installed via wheel
204 :target: https://pypi.org/project/amqp/
205
206 .. |pyversion| image:: https://img.shields.io/pypi/pyversions/amqp.svg
207 :alt: Supported Python versions.
208 :target: https://pypi.org/project/amqp/
209
210 .. |pyimp| image:: https://img.shields.io/pypi/implementation/amqp.svg
211 :alt: Support Python implementations.
212 :target: https://pypi.org/project/amqp/
213
214 py-amqp as part of the Tidelift Subscription
215 ============================================
216
217 The maintainers of py-amqp and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/subscription/pkg/pypi-amqp?utm_source=pypi-amqp&utm_medium=referral&utm_campaign=readme&utm_term=repo)
218
219
10220 Keywords: amqp rabbitmq cloudamqp messaging
11221 Platform: any
12222 Classifier: Development Status :: 5 - Production/Stable
22232 Classifier: Intended Audience :: Developers
23233 Classifier: Operating System :: OS Independent
24234 Requires-Python: >=3.6
235 Description-Content-Type: text/x-rst
0 :Version: 5.0.3
0 :Version: 5.0.6
11 :Web: https://amqp.readthedocs.io/
22 :Download: https://pypi.org/project/amqp/
33 :Source: http://github.com/celery/py-amqp/
00 #!/usr/bin/env python
11
2 import codecs
3 import os
42 import re
53 import sys
4 from os import environ
5 from pathlib import Path
66
77 import setuptools
88 import setuptools.command.test
4444
4545 pats = {re_meta: add_default,
4646 re_doc: add_doc}
47 here = os.path.abspath(os.path.dirname(__file__))
48 with open(os.path.join(here, 'amqp/__init__.py')) as meta_fh:
49 meta = {}
50 for line in meta_fh:
51 if line.strip() == '# -eof meta-':
52 break
53 for pattern, handler in pats.items():
54 m = pattern.match(line.strip())
55 if m:
56 meta.update(handler(m))
47 here = Path(__file__).parent
48 meta = {}
49 for line in (here / 'amqp/__init__.py').read_text().splitlines():
50 if line.strip() == '# -eof meta-':
51 break
52 for pattern, handler in pats.items():
53 m = pattern.match(line.strip())
54 if m:
55 meta.update(handler(m))
5756
5857 # -*- Installation Requires -*-
5958
6766
6867
6968 def reqs(f):
70 with open(os.path.join(os.getcwd(), 'requirements', f)) as fp:
71 req = filter(None, [strip_comments(l) for l in fp.readlines()])
72 # filter returns filter object(iterator) in Python 3,
73 # but a list in Python 2.7, so make sure it returns a list.
74 return list(req)
75
76
77 # -*- Long Description -*-
78
79 def long_description():
80 try:
81 return codecs.open('README.rst', 'r', 'utf-8').read()
82 except OSError:
83 return 'Long description error: Missing README.rst file'
69 lines = (here / 'requirements' / f).read_text().splitlines()
70 reqs = [strip_comments(l) for l in lines]
71 return list(filter(None, reqs))
8472
8573
8674 # -*- %%% -*-
9987 sys.exit(pytest.main(pytest_args))
10088
10189
102 if os.environ.get("CELERY_ENABLE_SPEEDUPS"):
90 if environ.get("CELERY_ENABLE_SPEEDUPS"):
10391 setup_requires = ['Cython']
10492 ext_modules = [
10593 setuptools.Extension(
132120 packages=setuptools.find_packages(exclude=['ez_setup', 't', 't.*']),
133121 version=meta['version'],
134122 description=meta['doc'],
123 long_description=(here / 'README.rst').read_text(),
124 long_description_content_type="text/x-rst",
135125 keywords='amqp rabbitmq cloudamqp messaging',
136126 author=meta['author'],
137127 author_email=meta['contact'],
44 import pytest
55
66 import amqp
7 from amqp import transport
78
89
910 def get_connection(
6768 use_tls=True,
6869 keyfile='t/certs/client_key_broken.pem',
6970 certfile='t/certs/client_certificate_broken.pem'
71 )
72 with pytest.raises(ssl.SSLError):
73 connection.connect()
74
75
76 @pytest.mark.env('rabbitmq')
77 @pytest.mark.flaky(reruns=5, reruns_delay=2)
78 def test_tls_default_certs():
79 # testing TLS connection against badssl.com with default certs
80 connection = transport.Transport(
81 host="tls-v1-2.badssl.com:1012",
82 ssl=True,
83 )
84 assert type(connection) == transport.SSLTransport
85 connection.connect()
86
87
88 @pytest.mark.env('rabbitmq')
89 @pytest.mark.flaky(reruns=5, reruns_delay=2)
90 def test_tls_no_default_certs_fails():
91 # testing TLS connection fails against badssl.com without default certs
92 connection = transport.Transport(
93 host="tls-v1-2.badssl.com:1012",
94 ssl={
95 "ca_certs": 't/certs/ca_certificate.pem',
96 },
7097 )
7198 with pytest.raises(ssl.SSLError):
7299 connection.connect()
00 import errno
11 import os
22 import re
3 import ssl
34 import socket
45 import struct
56 from struct import pack
638639
639640 def test_wrap_socket_sni(self):
640641 # testing default values of _wrap_socket_sni()
641 sock = Mock()
642642 with patch('ssl.SSLContext') as mock_ssl_context_class:
643 wrap_socket_method_mock = mock_ssl_context_class().wrap_socket
644 wrap_socket_method_mock.return_value = sentinel.WRAPPED_SOCKET
643 sock = Mock()
644 context = mock_ssl_context_class()
645 context.wrap_socket.return_value = sentinel.WRAPPED_SOCKET
645646 ret = self.t._wrap_socket_sni(sock)
646647
647 mock_ssl_context_class.load_cert_chain.assert_not_called()
648 mock_ssl_context_class.load_verify_locations.assert_not_called()
649 mock_ssl_context_class.set_ciphers.assert_not_called()
650 mock_ssl_context_class.verify_mode.assert_not_called()
651 wrap_socket_method_mock.assert_called_with(
652 sock=sock,
653 server_side=False,
654 do_handshake_on_connect=False,
655 suppress_ragged_eofs=True,
656 server_hostname=None
657 )
658 assert ret == sentinel.WRAPPED_SOCKET
648 context.load_cert_chain.assert_not_called()
649 context.load_verify_locations.assert_not_called()
650 context.set_ciphers.assert_not_called()
651 context.verify_mode.assert_not_called()
652
653 context.load_default_certs.assert_called_with(
654 ssl.Purpose.SERVER_AUTH
655 )
656 context.wrap_socket.assert_called_with(
657 sock=sock,
658 server_side=False,
659 do_handshake_on_connect=False,
660 suppress_ragged_eofs=True,
661 server_hostname=None
662 )
663 assert ret == sentinel.WRAPPED_SOCKET
659664
660665 def test_wrap_socket_sni_certfile(self):
661666 # testing _wrap_socket_sni() with parameters certfile and keyfile
662667 with patch('ssl.SSLContext') as mock_ssl_context_class:
663 load_cert_chain_method_mock = \
664 mock_ssl_context_class().load_cert_chain
668 sock = Mock()
669 context = mock_ssl_context_class()
665670 self.t._wrap_socket_sni(
666 Mock(), keyfile=sentinel.KEYFILE, certfile=sentinel.CERTFILE
667 )
668
669 load_cert_chain_method_mock.assert_called_with(
670 sentinel.CERTFILE, sentinel.KEYFILE
671 )
671 sock, keyfile=sentinel.KEYFILE, certfile=sentinel.CERTFILE
672 )
673
674 context.load_default_certs.assert_called_with(
675 ssl.Purpose.SERVER_AUTH
676 )
677 context.load_cert_chain.assert_called_with(
678 sentinel.CERTFILE, sentinel.KEYFILE
679 )
672680
673681 def test_wrap_socket_ca_certs(self):
674682 # testing _wrap_socket_sni() with parameter ca_certs
675683 with patch('ssl.SSLContext') as mock_ssl_context_class:
676 load_verify_locations_method_mock = \
677 mock_ssl_context_class().load_verify_locations
678 self.t._wrap_socket_sni(Mock(), ca_certs=sentinel.CA_CERTS)
679
680 load_verify_locations_method_mock.assert_called_with(sentinel.CA_CERTS)
684 sock = Mock()
685 context = mock_ssl_context_class()
686 self.t._wrap_socket_sni(sock, ca_certs=sentinel.CA_CERTS)
687
688 context.load_default_certs.assert_not_called()
689 context.load_verify_locations.assert_called_with(sentinel.CA_CERTS)
681690
682691 def test_wrap_socket_ciphers(self):
683692 # testing _wrap_socket_sni() with parameter ciphers
684693 with patch('ssl.SSLContext') as mock_ssl_context_class:
685 set_ciphers_method_mock = mock_ssl_context_class().set_ciphers
686 self.t._wrap_socket_sni(Mock(), ciphers=sentinel.CIPHERS)
687
688 set_ciphers_method_mock.assert_called_with(sentinel.CIPHERS)
694 sock = Mock()
695 context = mock_ssl_context_class()
696 set_ciphers_method_mock = context.set_ciphers
697 self.t._wrap_socket_sni(sock, ciphers=sentinel.CIPHERS)
698
699 set_ciphers_method_mock.assert_called_with(sentinel.CIPHERS)
689700
690701 def test_wrap_socket_sni_cert_reqs(self):
691 # testing _wrap_socket_sni() with parameter cert_reqs
692702 with patch('ssl.SSLContext') as mock_ssl_context_class:
693 self.t._wrap_socket_sni(Mock(), cert_reqs=sentinel.CERT_REQS)
694
695 assert mock_ssl_context_class().verify_mode == sentinel.CERT_REQS
703 sock = Mock()
704 context = mock_ssl_context_class()
705 self.t._wrap_socket_sni(sock, cert_reqs=ssl.CERT_NONE)
706
707 context.load_default_certs.assert_not_called()
708 assert context.verify_mode == ssl.CERT_NONE
709
710 # testing _wrap_socket_sni() with parameter cert_reqs != ssl.CERT_NONE
711 with patch('ssl.SSLContext') as mock_ssl_context_class:
712 sock = Mock()
713 context = mock_ssl_context_class()
714 self.t._wrap_socket_sni(sock, cert_reqs=sentinel.CERT_REQS)
715
716 context.load_default_certs.assert_called_with(
717 ssl.Purpose.SERVER_AUTH
718 )
719 assert context.verify_mode == sentinel.CERT_REQS
720
721 # testing context creation inside _wrap_socket_sni() with parameter
722 # cert_reqs == ssl.CERT_NONE. Previously raised ValueError because
723 # code path attempted to set context.verify_mode=ssl.CERT_NONE before
724 # setting context.check_hostname = False which raised a ValueError
725 with patch('ssl.SSLContext.wrap_socket') as mock_wrap_socket:
726 with patch('ssl.SSLContext.load_default_certs') as mock_load_default_certs:
727 sock = Mock()
728 self.t._wrap_socket_sni(
729 sock, server_side=True, cert_reqs=ssl.CERT_NONE
730 )
731 mock_load_default_certs.assert_not_called()
732 mock_wrap_socket.assert_called_once()
733
734 with patch('ssl.SSLContext.wrap_socket') as mock_wrap_socket:
735 with patch('ssl.SSLContext.load_default_certs') as mock_load_default_certs:
736 sock = Mock()
737 self.t._wrap_socket_sni(
738 sock, server_side=False, cert_reqs=ssl.CERT_NONE
739 )
740 mock_load_default_certs.assert_not_called()
741 mock_wrap_socket.assert_called_once()
742
743 with patch('ssl.SSLContext.wrap_socket') as mock_wrap_socket:
744 with patch('ssl.SSLContext.load_default_certs') as mock_load_default_certs:
745 sock = Mock()
746 self.t._wrap_socket_sni(
747 sock, server_side=True, cert_reqs=ssl.CERT_REQUIRED
748 )
749 mock_load_default_certs.assert_called_with(ssl.Purpose.CLIENT_AUTH)
750 mock_wrap_socket.assert_called_once()
751
752 with patch('ssl.SSLContext.wrap_socket') as mock_wrap_socket:
753 with patch('ssl.SSLContext.load_default_certs') as mock_load_default_certs:
754 sock = Mock()
755 self.t._wrap_socket_sni(
756 sock, server_side=False, cert_reqs=ssl.CERT_REQUIRED
757 )
758 mock_load_default_certs.assert_called_once_with(
759 ssl.Purpose.SERVER_AUTH
760 )
761 mock_wrap_socket.assert_called_once()
696762
697763 def test_wrap_socket_sni_setting_sni_header(self):
698764 # testing _wrap_socket_sni() without parameter server_hostname
765
699766 # SSL module supports SNI
700767 with patch('ssl.SSLContext') as mock_ssl_context_class, \
701768 patch('ssl.HAS_SNI', new=True):
702 self.t._wrap_socket_sni(Mock())
703
704 assert mock_ssl_context_class().check_hostname is False
769 sock = Mock()
770 context = mock_ssl_context_class()
771 self.t._wrap_socket_sni(sock)
772
773 assert context.check_hostname is False
705774
706775 # SSL module does not support SNI
707776 with patch('ssl.SSLContext') as mock_ssl_context_class, \
708777 patch('ssl.HAS_SNI', new=False):
709 self.t._wrap_socket_sni(Mock())
710
711 assert mock_ssl_context_class().check_hostname is False
778 sock = Mock()
779 context = mock_ssl_context_class()
780 self.t._wrap_socket_sni(sock)
781
782 assert context.check_hostname is False
712783
713784 # testing _wrap_socket_sni() with parameter server_hostname
714 sock = Mock()
785
786 # SSL module supports SNI
715787 with patch('ssl.SSLContext') as mock_ssl_context_class, \
716788 patch('ssl.HAS_SNI', new=True):
717 # SSL module supports SNI
718 wrap_socket_method_mock = mock_ssl_context_class().wrap_socket
789 sock = Mock()
790 context = mock_ssl_context_class()
719791 self.t._wrap_socket_sni(
720792 sock, server_hostname=sentinel.SERVER_HOSTNAME
721793 )
722794
723 wrap_socket_method_mock.assert_called_with(
724 sock=sock,
725 server_side=False,
726 do_handshake_on_connect=False,
727 suppress_ragged_eofs=True,
728 server_hostname=sentinel.SERVER_HOSTNAME
729 )
730 assert mock_ssl_context_class().check_hostname is True
731
795 context.wrap_socket.assert_called_with(
796 sock=sock,
797 server_side=False,
798 do_handshake_on_connect=False,
799 suppress_ragged_eofs=True,
800 server_hostname=sentinel.SERVER_HOSTNAME
801 )
802 assert context.check_hostname is True
803
804 # SSL module does not support SNI
732805 with patch('ssl.SSLContext') as mock_ssl_context_class, \
733806 patch('ssl.HAS_SNI', new=False):
734 # SSL module does not support SNI
735 wrap_socket_method_mock = mock_ssl_context_class().wrap_socket
807 sock = Mock()
808 context = mock_ssl_context_class()
736809 self.t._wrap_socket_sni(
737810 sock, server_hostname=sentinel.SERVER_HOSTNAME
738811 )
739 wrap_socket_method_mock.assert_called_with(
740 sock=sock,
741 server_side=False,
742 do_handshake_on_connect=False,
743 suppress_ragged_eofs=True,
744 server_hostname=sentinel.SERVER_HOSTNAME
745 )
746 assert mock_ssl_context_class().check_hostname is False
812
813 context.wrap_socket.assert_called_with(
814 sock=sock,
815 server_side=False,
816 do_handshake_on_connect=False,
817 suppress_ragged_eofs=True,
818 server_hostname=sentinel.SERVER_HOSTNAME
819 )
820 assert context.check_hostname is False
747821
748822 def test_shutdown_transport(self):
749823 self.t.sock = None