diff --git a/faststream/specification/asyncapi/v2_6_0/generate.py b/faststream/specification/asyncapi/v2_6_0/generate.py index 4c81514da7..8729ad9fb7 100644 --- a/faststream/specification/asyncapi/v2_6_0/generate.py +++ b/faststream/specification/asyncapi/v2_6_0/generate.py @@ -1,3 +1,4 @@ +import warnings from collections.abc import Sequence from typing import TYPE_CHECKING, Any, Optional, Union @@ -204,8 +205,14 @@ def _resolve_msg_payloads( payloads.update(m.payload.pop(DEF_KEY, {})) p_title = m.payload.get("title", f"{channel_name}Payload") p_title = clear_key(p_title) - if p_title not in payloads: - payloads[p_title] = m.payload + if p_title in payloads: + warnings.warn( + f"Overwriting the message schema, data types have the same name: `{p_title}`", + RuntimeWarning, + stacklevel=1, + ) + + payloads[p_title] = m.payload m.payload = {"$ref": f"#/components/schemas/{p_title}"} else: diff --git a/faststream/specification/asyncapi/v3_0_0/generate.py b/faststream/specification/asyncapi/v3_0_0/generate.py index ddd2026e3b..ea9468b2af 100644 --- a/faststream/specification/asyncapi/v3_0_0/generate.py +++ b/faststream/specification/asyncapi/v3_0_0/generate.py @@ -1,3 +1,4 @@ +import warnings from collections.abc import Sequence from typing import TYPE_CHECKING, Any, Optional, Union from urllib.parse import urlparse @@ -229,6 +230,14 @@ def _resolve_msg_payloads( payloads.update(m.payload.pop(DEF_KEY, {})) payload_name = m.payload.get("title", f"{channel_name}:{message_name}:Payload") payload_name = clear_key(payload_name) + + if payload_name in payloads: + warnings.warn( + f"Overwriting the message schema, data types have the same name: `{payload_name}`", + RuntimeWarning, + stacklevel=1, + ) + payloads[payload_name] = m.payload m.payload = {"$ref": f"#/components/schemas/{payload_name}"} assert m.title diff --git a/tests/asyncapi/base/v2_6_0/arguments.py b/tests/asyncapi/base/v2_6_0/arguments.py index aaac817e85..a7aa9984e9 100644 --- a/tests/asyncapi/base/v2_6_0/arguments.py +++ b/tests/asyncapi/base/v2_6_0/arguments.py @@ -3,6 +3,7 @@ from typing import Annotated, Any, Optional, Union import pydantic +import pytest from dirty_equals import IsDict, IsPartialDict, IsStr from fast_depends import Depends from typing_extensions import Literal @@ -697,3 +698,42 @@ async def handle( "type": "object", }, ) + + def test_overwrite_schema(self) -> None: + @dataclass + class User: + id: int + name: str = "" + + broker = self.broker_class() + + @broker.subscriber("test") + async def handle(user: User) -> None: ... + + @dataclass + class User: + id: int + email: str = "" + + @broker.subscriber("test2") + async def second_handle(user: User) -> None: ... + + with pytest.warns(RuntimeWarning, match="Overwriting the message schema, data types have the same name"): + schema = AsyncAPI(self.build_app(broker), schema_version="2.6.0").to_jsonable() + + payload = schema["components"]["schemas"] + + assert len(payload) == 1 + + key, value = next(iter(payload.items())) + + assert key == "User" + assert value == { + "properties": { + "id": {"title": "Id", "type": "integer"}, + "email": {"default": "", "title": "Email", "type": "string"}, + }, + "required": ["id"], + "title": key, + "type": "object", + } diff --git a/tests/asyncapi/base/v3_0_0/arguments.py b/tests/asyncapi/base/v3_0_0/arguments.py index ca4ee949ab..d93833a85d 100644 --- a/tests/asyncapi/base/v3_0_0/arguments.py +++ b/tests/asyncapi/base/v3_0_0/arguments.py @@ -3,6 +3,7 @@ from typing import Annotated, Optional, Union import pydantic +import pytest from dirty_equals import IsDict, IsPartialDict, IsStr from fast_depends import Depends from fastapi import Depends as APIDepends @@ -681,3 +682,42 @@ async def handle( "type": "object", }, ) + + def test_overwrite_schema(self) -> None: + @dataclass + class User: + id: int + name: str = "" + + broker = self.broker_factory() + + @broker.subscriber("test") + async def handle(user: User) -> None: ... + + @dataclass + class User: + id: int + email: str = "" + + @broker.subscriber("test2") + async def second_handle(user: User) -> None: ... + + with pytest.warns(RuntimeWarning, match="Overwriting the message schema, data types have the same name"): + schema = AsyncAPI(self.build_app(broker), schema_version="3.0.0").to_jsonable() + + payload = schema["components"]["schemas"] + + assert len(payload) == 1 + + key, value = next(iter(payload.items())) + + assert key == "User" + assert value == { + "properties": { + "id": {"title": "Id", "type": "integer"}, + "email": {"default": "", "title": "Email", "type": "string"}, + }, + "required": ["id"], + "title": key, + "type": "object", + }