diff --git a/docs/docs/en/rabbit/declare.md b/docs/docs/en/rabbit/declare.md index 502d97dfbb..7bc8f2bfc3 100644 --- a/docs/docs/en/rabbit/declare.md +++ b/docs/docs/en/rabbit/declare.md @@ -10,6 +10,8 @@ search: # RabbitMQ Queue/Exchange Declaration +## Declaring queues and exchanges + **FastStream** *subscribers* declares and validates all using *RabbitMQ* exchanges and queues (*publishers* declares exchanges only), but sometimes you need to declare them manually. **RabbitBroker** provides a way to achieve this easily. @@ -22,3 +24,12 @@ These methods require just one argument (`RabbitQueue`/`RabbitExchange`) contain !!! tip Also, these methods are idempotent, so you can call them with the same arguments multiple times, but the objects will be created once; next time the method will return an already stored object. This way you can get access to any queue/exchange created automatically. + + +## Binding a queue to an exchange + +It is also possible to bind a queue and an exchange using low-level **aio-pika** `RobustQueue.bind` method: + +```python linenums="1" hl_lines="24-26 28-30 32-35" +{! docs_src/rabbit/bind.py !} +``` diff --git a/docs/docs_src/rabbit/bind.py b/docs/docs_src/rabbit/bind.py new file mode 100644 index 0000000000..d8d2b466d1 --- /dev/null +++ b/docs/docs_src/rabbit/bind.py @@ -0,0 +1,37 @@ +import aio_pika +from faststream import FastStream +from faststream.rabbit import ( + ExchangeType, + RabbitBroker, + RabbitExchange, + RabbitQueue, +) + +broker = RabbitBroker() +app = FastStream(broker) + + +some_queue = RabbitQueue( + name="some-queue", + durable=True, +) + +some_exchange = RabbitExchange( + name="some-exchange", + type=ExchangeType.FANOUT, +) + +@app.after_startup +async def bind_queue_exchange(): + queue: aio_pika.RobustQueue = await broker.declare_queue( + some_queue + ) + + exchange: aio_pika.RobustExchange = await broker.declare_exchange( + some_exchange + ) + + await queue.bind( + exchange=exchange, + routing_key=queue.name # Optional parameter + ) diff --git a/tests/a_docs/rabbit/test_bind.py b/tests/a_docs/rabbit/test_bind.py new file mode 100644 index 0000000000..d2656a6f5c --- /dev/null +++ b/tests/a_docs/rabbit/test_bind.py @@ -0,0 +1,30 @@ +from unittest.mock import AsyncMock + +import pytest +from aio_pika import RobustQueue + +from faststream import TestApp +from tests.marks import require_aiopika + + +@pytest.mark.asyncio +@pytest.mark.rabbit +@require_aiopika +async def test_bind(monkeypatch, async_mock: AsyncMock): + from docs.docs_src.rabbit.bind import app, broker, some_exchange, some_queue + + with monkeypatch.context() as m: + m.setattr(RobustQueue, "bind", async_mock) + + async with TestApp(app): + assert len(broker.declarer._RabbitDeclarer__queues) == 2 # with `reply-to` + assert len(broker.declarer._RabbitDeclarer__exchanges) == 1 + + assert some_queue in broker.declarer._RabbitDeclarer__queues + assert some_exchange in broker.declarer._RabbitDeclarer__exchanges + + row_exchange = await broker.declarer.declare_exchange(some_exchange) + async_mock.assert_awaited_once_with( + exchange=row_exchange, + routing_key=some_queue.name, + )