rabbitmq-amqp-python-client 0.7.0__tar.gz → 0.8.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/PKG-INFO +2 -2
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/README.md +1 -1
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/pyproject.toml +1 -1
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/rabbitmq_amqp_python_client/__init__.py +2 -0
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/rabbitmq_amqp_python_client/asyncio/environment.py +32 -13
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/rabbitmq_amqp_python_client/connection.py +3 -0
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/rabbitmq_amqp_python_client/entities.py +42 -0
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/rabbitmq_amqp_python_client/environment.py +30 -12
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/rabbitmq_amqp_python_client/utils.py +3 -2
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/LICENSE +0 -0
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/rabbitmq_amqp_python_client/address_helper.py +0 -0
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/rabbitmq_amqp_python_client/amqp_consumer_handler.py +0 -0
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/rabbitmq_amqp_python_client/asyncio/__init__.py +0 -0
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/rabbitmq_amqp_python_client/asyncio/connection.py +0 -0
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/rabbitmq_amqp_python_client/asyncio/consumer.py +0 -0
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/rabbitmq_amqp_python_client/asyncio/management.py +0 -0
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/rabbitmq_amqp_python_client/asyncio/publisher.py +0 -0
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/rabbitmq_amqp_python_client/common.py +0 -0
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/rabbitmq_amqp_python_client/consumer.py +0 -0
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/rabbitmq_amqp_python_client/delivery_context.py +0 -0
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/rabbitmq_amqp_python_client/exceptions.py +0 -0
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/rabbitmq_amqp_python_client/management.py +0 -0
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/rabbitmq_amqp_python_client/options.py +0 -0
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/rabbitmq_amqp_python_client/publisher.py +0 -0
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/rabbitmq_amqp_python_client/py.typed +0 -0
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/rabbitmq_amqp_python_client/qpid/proton/__init__.py +0 -0
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/rabbitmq_amqp_python_client/qpid/proton/_common.py +0 -0
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/rabbitmq_amqp_python_client/qpid/proton/_condition.py +0 -0
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/rabbitmq_amqp_python_client/qpid/proton/_data.py +0 -0
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/rabbitmq_amqp_python_client/qpid/proton/_delivery.py +0 -0
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/rabbitmq_amqp_python_client/qpid/proton/_endpoints.py +0 -0
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/rabbitmq_amqp_python_client/qpid/proton/_events.py +0 -0
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/rabbitmq_amqp_python_client/qpid/proton/_exceptions.py +0 -0
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/rabbitmq_amqp_python_client/qpid/proton/_flow_properties.py +0 -0
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/rabbitmq_amqp_python_client/qpid/proton/_handler.py +0 -0
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/rabbitmq_amqp_python_client/qpid/proton/_handlers.py +0 -0
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/rabbitmq_amqp_python_client/qpid/proton/_io.py +0 -0
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/rabbitmq_amqp_python_client/qpid/proton/_message.py +0 -0
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/rabbitmq_amqp_python_client/qpid/proton/_reactor.py +0 -0
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/rabbitmq_amqp_python_client/qpid/proton/_selectable.py +0 -0
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/rabbitmq_amqp_python_client/qpid/proton/_tracing.py +0 -0
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/rabbitmq_amqp_python_client/qpid/proton/_transport.py +0 -0
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/rabbitmq_amqp_python_client/qpid/proton/_url.py +0 -0
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/rabbitmq_amqp_python_client/qpid/proton/_utils.py +0 -0
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/rabbitmq_amqp_python_client/qpid/proton/_wrapper.py +0 -0
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/rabbitmq_amqp_python_client/qpid/proton/handlers.py +0 -0
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/rabbitmq_amqp_python_client/qpid/proton/py.typed +0 -0
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/rabbitmq_amqp_python_client/qpid/proton/reactor.py +0 -0
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/rabbitmq_amqp_python_client/qpid/proton/tracing.py +0 -0
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/rabbitmq_amqp_python_client/qpid/proton/utils.py +0 -0
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/rabbitmq_amqp_python_client/queues.py +0 -0
- {rabbitmq_amqp_python_client-0.7.0 → rabbitmq_amqp_python_client-0.8.0}/rabbitmq_amqp_python_client/ssl_configuration.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rabbitmq-amqp-python-client
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.8.0
|
|
4
4
|
Summary: Python RabbitMQ client for AMQP 1.0 protocol
|
|
5
5
|
License: Apache-2.0 license
|
|
6
6
|
License-File: LICENSE
|
|
@@ -19,7 +19,7 @@ Requires-Dist: typing-extensions (>=4.15.0,<5.0.0)
|
|
|
19
19
|
Description-Content-Type: text/markdown
|
|
20
20
|
|
|
21
21
|
## RabbitMQ AMQP 1.0 Python Client
|
|
22
|
-
This library is meant to be used with RabbitMQ `4.x`.
|
|
22
|
+
This library is meant to be used with RabbitMQ `4.x`.
|
|
23
23
|
|
|
24
24
|
The client is distributed via [`PIP`](https://pypi.org/project/rabbitmq-amqp-python-client/):
|
|
25
25
|
```bash
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
## RabbitMQ AMQP 1.0 Python Client
|
|
2
|
-
This library is meant to be used with RabbitMQ `4.x`.
|
|
2
|
+
This library is meant to be used with RabbitMQ `4.x`.
|
|
3
3
|
|
|
4
4
|
The client is distributed via [`PIP`](https://pypi.org/project/rabbitmq-amqp-python-client/):
|
|
5
5
|
```bash
|
|
@@ -15,6 +15,7 @@ from .connection import Connection
|
|
|
15
15
|
from .consumer import Consumer
|
|
16
16
|
from .entities import (
|
|
17
17
|
AbcConsumerOptions,
|
|
18
|
+
AmqpUri,
|
|
18
19
|
ConsumerOptions,
|
|
19
20
|
ConsumerSettleStrategy,
|
|
20
21
|
ExchangeCustomSpecification,
|
|
@@ -73,6 +74,7 @@ del metadata
|
|
|
73
74
|
OutcomeState = Disposition
|
|
74
75
|
|
|
75
76
|
__all__ = [
|
|
77
|
+
"AmqpUri",
|
|
76
78
|
"Connection",
|
|
77
79
|
"Management",
|
|
78
80
|
"ExchangeSpecification",
|
|
@@ -4,7 +4,11 @@ import asyncio
|
|
|
4
4
|
import logging
|
|
5
5
|
from typing import Optional, Union
|
|
6
6
|
|
|
7
|
-
from ..entities import
|
|
7
|
+
from ..entities import (
|
|
8
|
+
AmqpUri,
|
|
9
|
+
OAuth2Options,
|
|
10
|
+
RecoveryConfiguration,
|
|
11
|
+
)
|
|
8
12
|
from ..ssl_configuration import (
|
|
9
13
|
PosixSslConfigurationContext,
|
|
10
14
|
WinSslConfigurationContext,
|
|
@@ -38,6 +42,8 @@ class AsyncEnvironment:
|
|
|
38
42
|
uri: Optional[str] = None,
|
|
39
43
|
# multi-node mode
|
|
40
44
|
uris: Optional[list[str]] = None,
|
|
45
|
+
# structured single-node mode
|
|
46
|
+
amqp_uri: Optional[AmqpUri] = None,
|
|
41
47
|
ssl_context: Union[
|
|
42
48
|
PosixSslConfigurationContext, WinSslConfigurationContext, None
|
|
43
49
|
] = None,
|
|
@@ -47,25 +53,38 @@ class AsyncEnvironment:
|
|
|
47
53
|
"""
|
|
48
54
|
Initialize AsyncEnvironment.
|
|
49
55
|
|
|
56
|
+
Exactly one of ``uri``, ``uris``, or ``amqp_uri`` must be provided.
|
|
57
|
+
|
|
50
58
|
Args:
|
|
51
|
-
uri: Single node connection URI
|
|
52
|
-
uris: List of
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
59
|
+
uri: Single node connection URI string (e.g. ``"amqp://guest:guest@localhost:5672/"``).
|
|
60
|
+
uris: List of URI strings for multi-node setup.
|
|
61
|
+
amqp_uri: Structured single-node connection parameters as an :class:`AmqpUri`
|
|
62
|
+
instance. Converted to a URI string internally.
|
|
63
|
+
ssl_context: SSL configuration for secure connections.
|
|
64
|
+
oauth2_options: OAuth2 options for authentication.
|
|
65
|
+
recovery_configuration: Configuration for connection recovery.
|
|
56
66
|
|
|
57
67
|
Raises:
|
|
58
|
-
ValueError: If
|
|
68
|
+
ValueError: If more than one of 'uri', 'uris', 'amqp_uri' is specified,
|
|
69
|
+
or if none is specified.
|
|
59
70
|
"""
|
|
60
|
-
|
|
71
|
+
set_count = sum(x is not None for x in [uri, uris, amqp_uri])
|
|
72
|
+
if set_count > 1:
|
|
73
|
+
raise ValueError(
|
|
74
|
+
"Cannot specify more than one of 'uri', 'uris', or 'amqp_uri'. "
|
|
75
|
+
"Choose one connection mode."
|
|
76
|
+
)
|
|
77
|
+
if set_count == 0:
|
|
61
78
|
raise ValueError(
|
|
62
|
-
"
|
|
79
|
+
"Must specify exactly one of 'uri', 'uris', or 'amqp_uri' for connection."
|
|
63
80
|
)
|
|
64
|
-
if uri is None and uris is None:
|
|
65
|
-
raise ValueError("Must specify either 'uri' or 'uris' for connection.")
|
|
66
81
|
|
|
67
|
-
|
|
68
|
-
|
|
82
|
+
if amqp_uri is not None:
|
|
83
|
+
self._uri: Optional[str] = amqp_uri.to_uri()
|
|
84
|
+
self._uris: Optional[list[str]] = None
|
|
85
|
+
else:
|
|
86
|
+
self._uri = uri
|
|
87
|
+
self._uris = uris
|
|
69
88
|
self._ssl_context = ssl_context
|
|
70
89
|
self._oauth2_options = oauth2_options
|
|
71
90
|
self._recovery_configuration = recovery_configuration
|
|
@@ -274,6 +274,9 @@ class Connection:
|
|
|
274
274
|
else:
|
|
275
275
|
typing_extensions.assert_never(self._conf_ssl_context)
|
|
276
276
|
self._ssl_domain.set_trusted_ca_db(ca_cert)
|
|
277
|
+
self._ssl_domain.set_peer_authentication(
|
|
278
|
+
SSLDomain.VERIFY_PEER_NAME, ca_cert
|
|
279
|
+
)
|
|
277
280
|
|
|
278
281
|
# for mutual authentication
|
|
279
282
|
if self._conf_ssl_context.client_cert is not None:
|
|
@@ -551,6 +551,48 @@ class RecoveryConfiguration:
|
|
|
551
551
|
MaxReconnectAttempts: int = 5
|
|
552
552
|
|
|
553
553
|
|
|
554
|
+
@dataclass
|
|
555
|
+
class AmqpUri:
|
|
556
|
+
"""
|
|
557
|
+
Configuration for an AMQP connection using individual fields.
|
|
558
|
+
|
|
559
|
+
Provides a structured alternative to a raw URI string, building the
|
|
560
|
+
connection URI from its component parts.
|
|
561
|
+
|
|
562
|
+
Attributes:
|
|
563
|
+
schema: The URI scheme (``"amqp"`` or ``"amqps"``). Defaults to ``"amqp"``.
|
|
564
|
+
host: The broker hostname or IP address. Defaults to ``"localhost"``.
|
|
565
|
+
port: The broker port. Defaults to ``5672``.
|
|
566
|
+
user: The authentication username. Defaults to ``"guest"``.
|
|
567
|
+
password: The authentication password. Defaults to ``"guest"``.
|
|
568
|
+
vhost: The target virtual host. Defaults to ``"/"``.
|
|
569
|
+
"""
|
|
570
|
+
|
|
571
|
+
schema: str = "amqp"
|
|
572
|
+
host: str = "localhost"
|
|
573
|
+
port: int = 5672
|
|
574
|
+
user: str = "guest"
|
|
575
|
+
password: str = "guest"
|
|
576
|
+
vhost: str = "/"
|
|
577
|
+
|
|
578
|
+
def to_uri(self) -> str:
|
|
579
|
+
"""
|
|
580
|
+
Build an AMQP URI string from the individual fields.
|
|
581
|
+
|
|
582
|
+
Returns:
|
|
583
|
+
str: A URI in the form ``schema://user:password@host:port/vhost``.
|
|
584
|
+
"""
|
|
585
|
+
from urllib.parse import quote
|
|
586
|
+
|
|
587
|
+
user_enc = quote(self.user, safe="")
|
|
588
|
+
password_enc = quote(self.password, safe="")
|
|
589
|
+
if self.vhost == "/":
|
|
590
|
+
vhost_path = "/"
|
|
591
|
+
else:
|
|
592
|
+
vhost_path = "/" + quote(self.vhost, safe="")
|
|
593
|
+
return f"{self.schema}://{user_enc}:{password_enc}@{self.host}:{self.port}{vhost_path}"
|
|
594
|
+
|
|
595
|
+
|
|
554
596
|
@dataclass
|
|
555
597
|
class OAuth2Options:
|
|
556
598
|
token: str
|
|
@@ -9,7 +9,11 @@ from typing import (
|
|
|
9
9
|
)
|
|
10
10
|
|
|
11
11
|
from .connection import Connection
|
|
12
|
-
from .entities import
|
|
12
|
+
from .entities import (
|
|
13
|
+
AmqpUri,
|
|
14
|
+
OAuth2Options,
|
|
15
|
+
RecoveryConfiguration,
|
|
16
|
+
)
|
|
13
17
|
from .ssl_configuration import (
|
|
14
18
|
PosixSslConfigurationContext,
|
|
15
19
|
WinSslConfigurationContext,
|
|
@@ -38,6 +42,8 @@ class Environment:
|
|
|
38
42
|
uri: Optional[str] = None,
|
|
39
43
|
# multi-node mode
|
|
40
44
|
uris: Optional[list[str]] = None,
|
|
45
|
+
# structured single-node mode
|
|
46
|
+
amqp_uri: Optional[AmqpUri] = None,
|
|
41
47
|
ssl_context: Union[
|
|
42
48
|
PosixSslConfigurationContext, WinSslConfigurationContext, None
|
|
43
49
|
] = None,
|
|
@@ -49,21 +55,33 @@ class Environment:
|
|
|
49
55
|
|
|
50
56
|
Creates an empty list to track active connections.
|
|
51
57
|
|
|
52
|
-
|
|
53
|
-
uri: Single node connection URI
|
|
54
|
-
uris: List of URIs for multi-node setup
|
|
55
|
-
ssl_context: SSL configuration for secure connections
|
|
56
|
-
on_disconnection_handler: Callback for handling disconnection events
|
|
58
|
+
Exactly one of ``uri``, ``uris``, or ``amqp_uri`` must be provided.
|
|
57
59
|
|
|
60
|
+
Args:
|
|
61
|
+
uri: Single node connection URI string (e.g. ``"amqp://guest:guest@localhost:5672/"``).
|
|
62
|
+
uris: List of URI strings for multi-node setup.
|
|
63
|
+
amqp_uri: Structured single-node connection parameters as an :class:`AmqpUri`
|
|
64
|
+
instance. Converted to a URI string internally.
|
|
65
|
+
ssl_context: SSL configuration for secure connections.
|
|
66
|
+
oauth2_options: OAuth2 authentication options.
|
|
67
|
+
recovery_configuration: Automatic reconnection configuration.
|
|
58
68
|
"""
|
|
59
|
-
|
|
69
|
+
set_count = sum(x is not None for x in [uri, uris, amqp_uri])
|
|
70
|
+
if set_count > 1:
|
|
71
|
+
raise ValueError(
|
|
72
|
+
"Cannot specify more than one of 'uri', 'uris', or 'amqp_uri'. "
|
|
73
|
+
"Choose one connection mode."
|
|
74
|
+
)
|
|
75
|
+
if set_count == 0:
|
|
60
76
|
raise ValueError(
|
|
61
|
-
"
|
|
77
|
+
"Must specify exactly one of 'uri', 'uris', or 'amqp_uri' for connection."
|
|
62
78
|
)
|
|
63
|
-
if
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
79
|
+
if amqp_uri is not None:
|
|
80
|
+
self._uri: Optional[str] = amqp_uri.to_uri()
|
|
81
|
+
self._uris: Optional[list[str]] = None
|
|
82
|
+
else:
|
|
83
|
+
self._uri = uri
|
|
84
|
+
self._uris = uris
|
|
67
85
|
self._ssl_context = ssl_context
|
|
68
86
|
self._recovery_configuration = recovery_configuration
|
|
69
87
|
self._connections: list[Connection] = []
|
|
@@ -12,17 +12,18 @@ def validate_annotations(annotations: []) -> bool: # type: ignore
|
|
|
12
12
|
class Converter:
|
|
13
13
|
|
|
14
14
|
@staticmethod
|
|
15
|
-
def bytes_to_string(body: bytes) -> str:
|
|
15
|
+
def bytes_to_string(body: bytes, encoding: str = "utf-8") -> str:
|
|
16
16
|
"""
|
|
17
17
|
Convert the body of a message to a string.
|
|
18
18
|
|
|
19
19
|
Args:
|
|
20
20
|
body: The body of the message
|
|
21
|
+
encoding: The character encoding to use for decoding (default: utf-8)
|
|
21
22
|
|
|
22
23
|
Returns:
|
|
23
24
|
str: The string representation of the body
|
|
24
25
|
"""
|
|
25
|
-
return
|
|
26
|
+
return bytes(body).decode(encoding)
|
|
26
27
|
|
|
27
28
|
@staticmethod
|
|
28
29
|
def string_to_bytes(body: str) -> bytes:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|