Skip to content

Commit

Permalink
Overwrite message schema (#2007)
Browse files Browse the repository at this point in the history
* fix: use of overwritten message scheme and warning

* test: overwrite schema and warning

* test: deleted the loop and made a length check
  • Loading branch information
ApostolFet authored Dec 25, 2024
1 parent 094b7f4 commit 8737347
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 2 deletions.
11 changes: 9 additions & 2 deletions faststream/specification/asyncapi/v2_6_0/generate.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import warnings
from collections.abc import Sequence
from typing import TYPE_CHECKING, Any, Optional, Union

Expand Down Expand Up @@ -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:
Expand Down
9 changes: 9 additions & 0 deletions faststream/specification/asyncapi/v3_0_0/generate.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import warnings
from collections.abc import Sequence
from typing import TYPE_CHECKING, Any, Optional, Union
from urllib.parse import urlparse
Expand Down Expand Up @@ -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
Expand Down
40 changes: 40 additions & 0 deletions tests/asyncapi/base/v2_6_0/arguments.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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",
}
40 changes: 40 additions & 0 deletions tests/asyncapi/base/v3_0_0/arguments.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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",
}

0 comments on commit 8737347

Please sign in to comment.