From 7badf7f8af8c74be21b4ae0528803d2cceaa1115 Mon Sep 17 00:00:00 2001 From: Maximilian Albert Date: Thu, 20 Jun 2024 19:33:55 +0100 Subject: [PATCH 1/7] docs: update CONTRIBUTING.md Added missing 'and not confluent' to pytest command for running the tests when no broker instances are present. --- docs/docs/en/getting-started/contributing/CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/en/getting-started/contributing/CONTRIBUTING.md b/docs/docs/en/getting-started/contributing/CONTRIBUTING.md index 9818aea06c..745f963830 100644 --- a/docs/docs/en/getting-started/contributing/CONTRIBUTING.md +++ b/docs/docs/en/getting-started/contributing/CONTRIBUTING.md @@ -94,7 +94,7 @@ pytest -m 'all' If you don't have a local broker instance running, you can run tests without those dependencies: ```bash -pytest -m 'not rabbit and not kafka and not nats and not redis' +pytest -m 'not rabbit and not kafka and not nats and not redis and not confluent' ``` To run tests based on RabbitMQ, Kafka, or other dependencies, the following dependencies are needed to be started as docker containers: From 2a89a0fadacb6c1f56739d9512df71054d2871c3 Mon Sep 17 00:00:00 2001 From: Maximilian Albert Date: Thu, 20 Jun 2024 21:07:08 +0100 Subject: [PATCH 2/7] feat: enable spy_decorator to wrap both async and non-async methods --- tests/tools.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/tests/tools.py b/tests/tools.py index b1fc8e52c4..2fe189de6e 100644 --- a/tests/tools.py +++ b/tests/tools.py @@ -1,3 +1,4 @@ +import inspect from typing import Any, Iterable from unittest.mock import MagicMock @@ -5,9 +6,14 @@ def spy_decorator(method): mock = MagicMock() - async def wrapper(*args, **kwargs): - mock(*args, **kwargs) - return await method(*args, **kwargs) + if inspect.iscoroutinefunction(method): + async def wrapper(*args, **kwargs): + mock(*args, **kwargs) + return await method(*args, **kwargs) + else: + def wrapper(*args, **kwargs): + mock(*args, **kwargs) + return method(*args, **kwargs) wrapper.mock = mock return wrapper From 7bd615144d57e47dfb619dd8e1cf15545aa33f42 Mon Sep 17 00:00:00 2001 From: Maximilian Albert Date: Thu, 20 Jun 2024 21:17:10 +0100 Subject: [PATCH 3/7] feat: add NatsBroker.new_inbox() --- faststream/nats/broker/broker.py | 9 +++++++++ tests/brokers/nats/test_new_inbox.py | 23 +++++++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 tests/brokers/nats/test_new_inbox.py diff --git a/faststream/nats/broker/broker.py b/faststream/nats/broker/broker.py index 35e35086c8..b7913b32d6 100644 --- a/faststream/nats/broker/broker.py +++ b/faststream/nats/broker/broker.py @@ -901,3 +901,12 @@ async def wrapper() -> None: self.__is_connected = True return wrapper + + async def new_inbox(self) -> str: + """Return a unique inbox that can be used for NATS requests or subscriptions. + + Calls `nats.aio.client.Client.new_inbox` [1] under the hood. + + [1] https://nats-io.github.io/nats.py/modules.html#nats.aio.client.Client.new_inbox + """ + return self._connection.new_inbox() diff --git a/tests/brokers/nats/test_new_inbox.py b/tests/brokers/nats/test_new_inbox.py new file mode 100644 index 0000000000..7969ad46a3 --- /dev/null +++ b/tests/brokers/nats/test_new_inbox.py @@ -0,0 +1,23 @@ +from unittest.mock import patch + +import pytest +from nats.aio.client import Client as NatsClient + +from faststream.nats import NatsBroker +from tests.tools import spy_decorator + + +@pytest.mark.asyncio() +@pytest.mark.nats() +async def test_new_inbox(): + with patch.object( + NatsClient, + "new_inbox", + spy_decorator(NatsClient.new_inbox), + ) as m: + broker = NatsBroker(inbox_prefix="_FOO_TEST_INBOX") + await broker.connect() + inbox_name = await broker.new_inbox() + + m.mock.assert_called_once() + assert inbox_name.startswith("_FOO_TEST_INBOX.") From 7b92dd140ccee9fc28647df456131152dee177c5 Mon Sep 17 00:00:00 2001 From: Maximilian Albert Date: Thu, 20 Jun 2024 21:21:54 +0100 Subject: [PATCH 4/7] chore: linting --- tests/brokers/nats/test_test_client.py | 1 - tests/tools.py | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/brokers/nats/test_test_client.py b/tests/brokers/nats/test_test_client.py index 94a4be5dac..e24cbb577e 100644 --- a/tests/brokers/nats/test_test_client.py +++ b/tests/brokers/nats/test_test_client.py @@ -91,7 +91,6 @@ async def test_inbox_prefix_with_real( assert br._connection._inbox_prefix == b"test" assert "test" in str(br._connection.new_inbox()) - async def test_respect_middleware(self, queue): routes = [] diff --git a/tests/tools.py b/tests/tools.py index 2fe189de6e..48df98a0a1 100644 --- a/tests/tools.py +++ b/tests/tools.py @@ -7,10 +7,12 @@ def spy_decorator(method): mock = MagicMock() if inspect.iscoroutinefunction(method): + async def wrapper(*args, **kwargs): mock(*args, **kwargs) return await method(*args, **kwargs) else: + def wrapper(*args, **kwargs): mock(*args, **kwargs) return method(*args, **kwargs) From 3e90aa4b8668db7c07a7e001ea61192b0ce163e2 Mon Sep 17 00:00:00 2001 From: Maximilian Albert Date: Thu, 20 Jun 2024 22:19:45 +0100 Subject: [PATCH 5/7] fix: raise error if new_inbox() is called before broker was started --- faststream/nats/broker/broker.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/faststream/nats/broker/broker.py b/faststream/nats/broker/broker.py index b7913b32d6..cc30fadeb3 100644 --- a/faststream/nats/broker/broker.py +++ b/faststream/nats/broker/broker.py @@ -909,4 +909,7 @@ async def new_inbox(self) -> str: [1] https://nats-io.github.io/nats.py/modules.html#nats.aio.client.Client.new_inbox """ + if not self._connection: + raise RuntimeError("Broker needs to be started before calling this method.") + return self._connection.new_inbox() From 0c2447aedbe95bf2566c5998c4fdd494400f9555 Mon Sep 17 00:00:00 2001 From: Maximilian Albert Date: Thu, 20 Jun 2024 22:59:37 +0100 Subject: [PATCH 6/7] refactor: use assert statement instead of raising an exception --- faststream/nats/broker/broker.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/faststream/nats/broker/broker.py b/faststream/nats/broker/broker.py index cc30fadeb3..765bf29bd1 100644 --- a/faststream/nats/broker/broker.py +++ b/faststream/nats/broker/broker.py @@ -909,7 +909,6 @@ async def new_inbox(self) -> str: [1] https://nats-io.github.io/nats.py/modules.html#nats.aio.client.Client.new_inbox """ - if not self._connection: - raise RuntimeError("Broker needs to be started before calling this method.") + assert self._connection # nosec B101 return self._connection.new_inbox() From 91addede9b37cb33d8146861e4d8d863d9c7edea Mon Sep 17 00:00:00 2001 From: Maximilian Albert Date: Fri, 21 Jun 2024 10:35:54 +0100 Subject: [PATCH 7/7] docs: mention 'inbox_prefix' argument in docstring for 'new_inbox()' --- faststream/nats/broker/broker.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/faststream/nats/broker/broker.py b/faststream/nats/broker/broker.py index 765bf29bd1..fefcc069a8 100644 --- a/faststream/nats/broker/broker.py +++ b/faststream/nats/broker/broker.py @@ -905,7 +905,9 @@ async def wrapper() -> None: async def new_inbox(self) -> str: """Return a unique inbox that can be used for NATS requests or subscriptions. - Calls `nats.aio.client.Client.new_inbox` [1] under the hood. + The inbox prefix can be customised by passing `inbox_prefix` when creating your `NatsBroker`. + + This method calls `nats.aio.client.Client.new_inbox` [1] under the hood. [1] https://nats-io.github.io/nats.py/modules.html#nats.aio.client.Client.new_inbox """